学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】
第三章、Spring的高级注解(Spring3.x及以上)1.配置Bean
Spring在3.x提供的新的注解,用于替换XML配置文件。
@Configurationpublic classAppConfig{}
问题:
- 配置Bean在应用的过程中替换了XML具体的什么内容?
AnnotationConfigApplicationContext
1.创建工厂代码ApplicationContext ctx = new AnnotationConfigApplicationContext();2.指定配置文件1. 指定配置bean的ClassApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);2. 指定配置bean所在的路径ApplicationContext ctx = new AnnotationConfigApplicationContext("com.baizhi");
- 配置Bean开发的细节分析
基于注解开发使用日志
不能集成Log4j(落后了)
集成新的日志技术:logback
引入相关jar
org.slf4j slf4j-api 1.7.26 org.slf4j jcl-over-slf4j 1.5.6 ch.qos.logback logback-classic 1.2.12 ch.qos.logback logback-core 1.2.12 org.logback-extensions logback-ext-spring 0.1.5
引入logback配置文件(logback.xml)
%d{yyyy-MM-dd HH:mm:ss.SSS} {%thread} %-5level %logger{50} - %msg%n
@Configuration注解的本质
本质:也是@Component注解的衍生注解
可以应用<context:component-scan进行扫描,但是实际开发不会这么做。
- 配置Bean开发的细节分析
2.@Bean注解
@Bean注解在配置bean中进行使用,等同于XML配置文件中的<bean标签
1.@Bean注解的基本使用
- 对象的创建
1. 简单对象 直接能够通关new方式创建的对象:User UserService UserDAO 2. 复杂对象 不能通过new方式创建的对象:Connection SqlSessionFactory ```java /** * 创建复杂对象 * Connection 不能直接通过new 创建 */ @Bean public Connection conn() { Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool?useSSL=false", "root", "123456"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } ``` - @Bean注解创建复杂对象的注意事项 ```java 遗留系统整合比较常见,自己写还是通过上面的方式 @Bean public Connection conn1(){ Connection conn = null; try { ConnectionFactoryBean factoryBean = new ConnectionFactoryBean(); conn = factoryBean.getObject(); } catch (Exception e) { e.printStackTrace(); } return conn; } ```
自定义id值
@Bean("id)
控制对象创建次数
@Bean@Scope("singleton | prototype") 默认值 singleton
2.@Bean注解的注入
用户自定义类型
@Beanpublic UserDao userDAO(){ return new UserDaoImpl();}//可以通过形参传入userDao,也可以调用方法获取userDao@Beanpublic UserService userService(){ UserServiceImpl userService = new UserServiceImpl(); userService.setUserDao(userDAO()); return userService;}
JDK类型的注入
@Beanpublic Customer customer(){ Customer customer = new Customer(); customer.setId(1); customer.setName("xiaohei"); return customer;}
JDK类型注入的细节分析
如果直接在代码中进行set方法的调用,会存在耦合的问题
@Configuration@PropertySource("classpath:/init.properties")public class AppConfig1 { @Value("${id}") private Integer id; @Value("${name}") private String name;@Bean public Customer customer(){ Customer customer = new Customer(); customer.setId(id); customer.setName(name); return customer; }}
3.@ComponentScan注解
@ComponentScan注解在配置bean中进行使用,等同于xml配置中的context:component-scan标签
目的:进行相关注解的扫描 @Component @Value…
1.基本使用
@Configuration@ComponentScan(basePackages = "com.baizhi.scan")public class AppConfig2 {}等价于:
2.排除、包含的使用
排除
@Configuration@ComponentScan(basePackages = "com.baizhi.scan", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class}) ,@ComponentScan.Filter(type = FilterType.ASPECTJ,pattern = "*..User1")})// 第一个排除Service注解,排除了user2对象,第二个排除了User1类public class AppConfig2 {}注意**:针对ASPECTJ和REGEX后面的值是pattern,其他都是value**
包含
@ComponentScan(basePackages = "com.baizhi.scan",useDefaultFilters = false,//放弃默认扫描策略,必须指定为falseincludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class})})public class AppConfig2 {}
4.Spring工厂创建对象的多种配置方式1.多种配置方式的应用场景 @Component @Bean @Import
2.配置优先级
@Component及其衍生注解 < @Bean < 配置文件bean标签
优先级高的配置 覆盖优先级低的配置(如果对@Component注解的类不满意,可以用@Bean注解的类进行覆盖,但是id必须同名)
@ImportResource("applicationContext.xml")// 与spring配置文件集成,先读取配置@Bean 在读取配置文件
- 解决基于注解进行配置的耦合问题
@Configuration@ImportResource("applicationContext.xml")public class AppConfig4 { @Bean public UserDao userDao() { return new UserDaoImpl(); }}**在applicationContext.xml 配置bean解耦合**
这样产生的问题,还是会有耦合,因为要在原有的AppConfig配置类添加集成代码,解决方法:
// 新建立一个AppConfig5的配置类,将集成代码放到此类中,再读取多个配置类,可以根据包地址读取所有的配置类ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig4.class,AppConfig5.class);ApplicationContext ctx1 = new AnnotationConfigApplicationContext("com.baizhi");UserDao userDao = (UserDao) ctx.getBean("userDAO");userDao.save();
5.整合多个配置信息
为什么会有多个配置信息
根绝不同类型(事务、数据库连接)拆分多个配置bean的开发,是一种模块化开发的形式,也体现了面向对象各司其职的设计思想
多配置信息整合的方式
- 多个配置bean的整合
- 配置Bean与@Component相关注解的整合
- 配置Bean与SpringXML配置文件的整合
整合多种配置
- 如何使多配置的信息 汇总成一个整体
- 实现跨配置的注入
1.多个配置Bean的整合
- 多配置信息汇总
- base-package进行多个配置Bean的整合
2. @Import 1. 可以创建对象 2. 多配置bean的整合
3. 在工厂创建时,指定多个配置Bean的Class对象 ```java // 这种方式日常开发使用较少,了解即可 ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig4.class,AppConfig5.class); ```
- 跨配置进行注入
**在应用配置Bean的过程中,不管使用哪种方式进行配置信息的汇总,其操作方式都是通过在成员变量添加@Autowired注解完成**@Configuration@Import(AppConfig2.class)public class AppConfig1 { @Autowired private UserDao userDAO; @Bean public UserService userService() { UserServiceImpl userService = new UserServiceImpl(); userService.setUserDao(userDAO); return userService; }}@Configurationpublic class AppConfig2 { @Bean public UserDao userDAO(){ return new UserDaoImpl(); }}
适用于应用配置Bean的所有场景
2.配置Bean与@Component相关注解的整合
@Component(@Repostitory)public class UserDAOImpl implements UserDAO{}@Configuration@ComponentScan("")public lcass AppConfig3{@Autowiredprivate UserDao userDao;@Bean public UserService userService() { UserServiceImpl userService = new UserServiceImpl(); userService.setUserDao(userDao); return userService; }}
3.配置Bean与配置文件整合
1.遗留系统的整合2.配置覆盖@Configuration@ImportResource("applicationContext.xml")public class AppConfig4 { @Autowired private UserDao userDao; @Bean public UserService userService() { UserServiceImpl userService = new UserServiceImpl(); userService.setUserDao(userDao); return userService; }}
6.配置Bean底层实现原理
Spring在配置Bean加入了@Configuration注解后,底层久会通过Cglib的代理方式,来进行对象相关的配置、处理
作者:扬眉剑出鞘
出处: https://www.cnblogs.com/eyewink/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。