文章目录
- 💨更多相关知识👇
-
- 一、依赖注入
-
- 🍂@Autowired注解
- ⚡扩展@PostConstruct的使用(@Autowired,构造方法,@PostConstruct的执行顺序)⚡
-
- ⚡扩展问题演示与解决
- ⭐@Autowired注解演示
- 🍂 @Qualifier注解
-
- ⭐@Qualifier注解演示
- 🍂 @Value注解
-
- ⭐@Value注解演示
- 二、PropertySource注解加载properties文件
-
- ⭐代码演示
- 三、第三方资源配置管理
-
- 🍁使用 @Bean注解 配置第三方资源bean
-
- ⭐代码演示
- 🍁 将独立的配置类加入核心配置
-
- ⭐导入式代码演示
- ⭐扫描式代码演示
- 🍁 简单类型与引用类型依赖注入
-
- ⭐代码演示
- 四、XML配置 和 注解配置的 区别
- 作者:KJ.JK
💨更多相关知识👇
💖Spring中的创建对象的三种方式、第三方资源配置管理详细描述及使用(XML版完结篇)
💖Spring中的bean的配置、作用范围、生命周期详细描述及使用(XML版上篇)
💖Spring中的依赖注入、setter与构造器注入、自动装配与集合注入详细描述及使用(XML版中篇)
💖异常处理与解决方案详解上篇
💖异常处理与解决方案详解下篇
💖Math类与System类的常用方法使用
💖JavaEE中的静态方法定义、方法重载要求、return作用详解
💖List接口的常用方法,精华总结
💖JavaEE中的Stream流的常用方法
💖JavaEE中的Stream流知识点使用,精华总结,一文直接上手
🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈
🍂个人博客首页: KJ.JK
欢迎大家点赞👍收藏💖评论💬关注🔒
💖源码获取 | 💻学习交流 | 🤝商务合作 | 💨私信作者
💨推荐一款实用的模拟面试、刷题练习算法的神器、适用于所有的程序猿👉点击开始免费刷题,跟着博主走上巅峰💪
一、依赖注入
🍂@Autowired注解
* 使用 "@Autowired注解"开启"自动装配模式" (默认按类型注入,如果有多个类型相同的按名称)
* @Autowired(required = false): 找不到就算了(会报错)
* 直接加在成员变量上使用
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public void setBookDao(BookDao bookDao) { //set方法可以省略
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
/*
注意:
自动装配基于反射设计创建对象并"暴力反射"对应属性为私有属性初始化数据,因此"无需提供setter方法"
自动装配建议使用无参构造方法创建对象(默认)
执行顺序:
构造方法执行 -> @Autowired注解执行注入
注意:如果一个类里面用到了静态代码块先初始化一些数据,而这些数据里面有一些代码又需要注入,这个时候如果有@Autowired为这些数据进行注入,会出现空指针异常,这个时候需要使用@PostConstruct注解(JDK8及以前有)
*/
⚡扩展@PostConstruct的使用(@Autowired,构造方法,@PostConstruct的执行顺序)⚡
"场景:当我们一个类里面有@Autowired注解注入对象,有构造方法,构造方法里面对象需要用@Autowired注解进行注入,这个时候会出现这个对象注入不成功为null,出现空指针异常,这个时候就需要@PostConstruct注解"
"@PostConstruct只有JDK8及以前有"
/*
静态代码块也是一样的道理
*/
⚡扩展问题演示与解决
"问题:"
public class AbController {
@Autowired
private AbService abService;
public AbController(){
abService.find(); //这里其实是为null,因为构造方法会先执行,然后再执行@Autowired,就会导致这个对象没有被注入报错
}
}
------------------------------------------------------------------------------------------------------------
"解决:"
/*
把代码放出构造方法外面,并里面在@Autowired注入对象后使用即可
*/
public class AbController {
@Autowired
private AbService abService;
public AbController(){
}
@PostConstruct //@PostConstruct注解来完成初始化, @PostConstruct注解的方法将会在abService注入完成后被自动调用
public void init() {
abService.find();
}
}
/*
执行顺序 :
构造方法 -> @Autowired -> @PostConstruct
*/
⭐@Autowired注解演示
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
// @Component // 默认id为类名首字母小写: bookServiceImpl
@Service
public class BookServiceImpl implements BookService {
// 自动装配,使用暴力反射,不需要提供set方法
// 默认是按照类型装配, 如果有多个,按照名字注入
@Autowired
private BookDao bookDao;
// public void setBookDao(BookDao bookDao) {
//
// this.bookDao = bookDao;
// }
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
🍂 @Qualifier注解
* 使用"@Qualifier注解"开启"指定名称"装配bean
* 直接在成员变量上面使用
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao")
private BookDao bookDao;
}
/*
注意:
@Qualifier注解无法单独使用,必须依赖@Autowired注解使用
*/
⭐@Qualifier注解演示
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
// @Component // 默认id为类名首字母小写: bookServiceImpl
@Service
public class BookServiceImpl implements BookService {
// 自动装配,使用暴力反射,不需要提供set方法
// 默认是按照类型装配, 如果有多个,按照名字注入,如果名字对不上,指定名称注入s
@Autowired
@Qualifier("bookDao2") // 指定自动装配 bookDao2, 必须要配合 @Autowired
private BookDao bookDao;
// public void setBookDao(BookDao bookDao) {
//
// this.bookDao = bookDao;
// }
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
🍂 @Value注解
* "用法1:"
使用 "@Value注解" 实现"简单类型 (8种基本数据类型+String) 注入"
* 直接在成员变量上使用即可(记得配置对应的基包扫描)
@Component
public class BookUtils {
@Value("100")
private int connectionNum;
}
------------------------------------------------------------------------------------------------------------
* "用法2: $:注入配置属性"
@Value("${tag}")
private String tag;
------------------------------------------------------------------------------------------------------------
* "用法3: #表达式值"
@Value("#{T(java.lang.Math).random()*1000.0}")
private double randomNumber;
⭐@Value注解演示
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class BookUtils {
@Value("mysql")
private String databaseName;
@Value("100")
private int connectionNumber;
@Override
public String toString() {
return "BookUtils{" +
"databaseName='" + databaseName + '\'' +
", connectionNumber=" + connectionNumber +
'}';
}
}
二、PropertySource注解加载properties文件
* 使用 "@PropertySource注解" 加载properties文件
* 使用el表达式可获取文件里面对应的值: ${}
* 例子 :
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
public class SpringConfig {
}
/*
注意:
路径仅支持单一文件配置,多文件请使用数组格式配置,不允许使用通配符*
*/
⭐代码演示
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class BookUtils {
@Value("${user.username}")
private String databaseName;
@Value("${user.connectionNum}")
private int connectionNumber;
@Override
public String toString() {
return "BookUtils{" +
"databaseName='" + databaseName + '\'' +
", connectionNumber=" + connectionNumber +
'}';
}
}
------------------------------------------------------------------------------------------------------------
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
@Configuration // Spring的配置类, 相当于applicationContext.xml
@ComponentScan({"com.itheima.dao", "com.itheima.service", "com.itheima.util"}) // 基包扫描
//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})
public class SpringConfig {
}
三、第三方资源配置管理
🍁使用 @Bean注解 配置第三方资源bean
* "@Bean注解"的作用:
1."放在方法上"
2."将方法的返回值放到Spring容器中"
3.可以指定对象的id,如果没有指定默认是"方法名字"
4.如果方法有参数,它会从容器中按类型匹配的方式获取,并且传入
* "@Bean注解的属性":
value: bean别名和name是相互依赖关联的,value,name如果都使用的话值必须要一致;
name: bean名称,"如果不写会默认为注解的方法名称";
autowire:自定装配默认是不开启的,建议尽量不要开启,因为自动装配不能装配基本数据类型、字符串、数组等,
这是自动装配设计的局限性,并且自动装配不如依赖注入精确;
initMethod: bean的初始化之前的执行方法,该参数一般不怎么用,因为完全可以在代码中实现;
destroyMethod:默认使用javaConfig配置的bean,如果存在close或者shutdown方法,
则在bean销毁时会自动执行该方法,如果你不想执行该方法,则添加@Bean(destroyMethod="")
来防止出发销毁方法
-----------------------------------------------------------------------------------------------------------
* 例子:
@Configuration
public class SpringConfig {
@Bean // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
//直接拿方法名,不用变化
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
}
⭐代码演示
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
@Configuration // Spring的配置类, 相当于applicationContext.xml
@ComponentScan({"com.itheima.dao", "com.itheima.service", "com.itheima.util"}) // 基包扫描
//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})
public class SpringConfig {
@Bean("ds") // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
//直接拿方法名,不用变化
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db?userSSL=false");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
}
------------------------------------------------------------------------------------------------------------
//测试类
@Test
public void test04() throws SQLException {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(SpringConfig.class);
DataSource dataSource = (DataSource) context.getBean("ds");
Connection conn = dataSource.getConnection();
System.out.println("conn = " + conn);
}
🍁 将独立的配置类加入核心配置
* 方式一: 导入式 (使用"@Import注解手动加入配置类到核心配置",此注解只能添加一次,"多个数据请用数组格式")
步骤: 配置类什么都不用做,核心配置类直接使用@Import注解导入该配置类即可
如: @Import({JdbcConfig.class, MyBatisConfig.class})
* 方式二: 扫描式 (使用@ComponentScan注解扫描配置类所在的包,加载对应的配置类信息)
步骤:
1.配置类需要配置"@Configuration注解"
2.核心配置类使用"@ComponentScan注解扫描配置类所在的包,带它上车"
⭐导入式代码演示
// Jdbc相关的配置类
import com.alibaba.druid.pool.DruidDataSource;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
public class JdbcConfig {
// @Bean: 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
@Bean("ds") // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
// 直接拿方法名,不用变化
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db?userSSL=false");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
}
-----------------------------------------------------------------------------------------------------------
//核心配置类
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
@Configuration // Spring的配置类, 相当于applicationContext.xml
@ComponentScan({"com.itheima.dao", "com.itheima.service", "com.itheima.util"}) // 基包扫描
//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})
@Import(JdbcConfig.class) // 方式一(推荐): @Import: 导入其他类,成为配置类
public class SpringConfig {
}
⭐扫描式代码演示
// Jdbc相关的配置类
import com.alibaba.druid.pool.DruidDataSource;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration // 方式二: 扫描式, 1.让这个类成为配置类 2.扫描这个包
public class JdbcConfig {
// @Bean: 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
@Bean("ds") // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
// 直接拿方法名,不用变化
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db?userSSL=false");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
}
------------------------------------------------------------------------------------------------------------
//核心配置类
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
@Configuration // Spring的配置类, 相当于applicationContext.xml
@ComponentScan({"com.itheima.dao", "com.itheima.service", "com.itheima.util", "com.itheima.config"}) // 基包扫描
//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})
public class SpringConfig {
}
🍁 简单类型与引用类型依赖注入
* 使用"@Value注解" 进行简单类型注入
* 引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象
⭐代码演示
// Jdbc相关的配置类
import com.alibaba.druid.pool.DruidDataSource;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
// @Bean: 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
@Bean("ds") // id叫ds
public DataSource dataSource(BookService service) {
// 假设方法需要参数, IoC容器会自动帮我们注入这个参数
System.out.println(service);
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
四、XML配置 和 注解配置的 区别
作者:KJ.JK
文章对你有所帮助的话,欢迎给个赞或者 star,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习
版权声明:程序员胖胖胖虎阿 发表于 2022年10月31日 上午11:08。
转载请注明:Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇) | 胖虎的工具箱-编程导航
转载请注明:Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇) | 胖虎的工具箱-编程导航
相关文章
暂无评论...