irpas技术客

Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)_KJ.JK

大大的周 5532

文章目录 💨更多相关知识👇一、依赖注入🍂@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,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #