天天看点

【Spring 高级注解】@Configuration、@Bean、@ComponentScan@Configuration:配置 Bean@Bean 注解@ComponentScan 注解Spring 工厂创建对象的多种方式整合多个配置信息四维一体的开发纯注解版AOP编程 …纯注解版 Spring + Mybatis 整合 …纯注解版事务编程YML 简介

Spring 高级注解(3.x以上)

  • @Configuration:配置 Bean
    • 基于注解开发使用日志 logback
  • @Bean 注解
    • @Bean 注解的基本使用
    • @Bean 注解的注入与细节
  • @ComponentScan 注解
  • Spring 工厂创建对象的多种方式
  • 整合多个配置信息
    • 多个配置 Bean 的整合
    • 配置 Bean 与 @Component 相关注解的整合
    • 配置 Bean 与配置文件整合
    • 配置 Bean 底层实现原理
  • 四维一体的开发
  • 纯注解版AOP编程 ...
  • 纯注解版 Spring + Mybatis 整合 ...
  • 纯注解版事务编程
  • YML 简介
笔记目录: 《孙哥说Spring5》学习笔记

@Configuration:配置 Bean

1、Spring 在 3.x 提供的新的注解

@Configuration

,用于替换 XML 配置文件

@Configuration
public class AppConfig {
}
           
  • 配置 Bean 在应用的过程中替换了 XML 具体什么内容呢?
    【Spring 高级注解】@Configuration、@Bean、@ComponentScan@Configuration:配置 Bean@Bean 注解@ComponentScan 注解Spring 工厂创建对象的多种方式整合多个配置信息四维一体的开发纯注解版AOP编程 …纯注解版 Spring + Mybatis 整合 …纯注解版事务编程YML 简介

2、使用了

@Configuration

后,用

AnnotationConfigApplicationContext

创建工厂:

方法1: 指定配置bean的Class
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

方法2: 指定配置bean所在的路径(某个包及其子包)
ApplicationContext ctx = new AnnotationConfigApplicationContext("com.yusael");
           

@Configuration

注解的本质:查看源码可知,它也是

@Component

注解的衍生注解

因此我们可以用

<context:component-scan

进行扫描,但我们不会这么做,因为注解就是为了取代 xml。

基于注解开发使用日志 logback

1、引入相关 jar:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.25</version>
</dependency>

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.25</version>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.3</version>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>1.2.3</version>
</dependency>

<dependency>
  <groupId>org.logback-extensions</groupId>
  <artifactId>logback-ext-spring</artifactId>
  <version>0.1.4</version>
</dependency>
           

2、引入 logback 配置文件:logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
           

@Bean 注解

@Bean

注解在配置 bean 中进行使用,等同于 XML 配置文件中的

<bean

标签

@Bean 注解的基本使用

对象的创建:

【Spring 高级注解】@Configuration、@Bean、@ComponentScan@Configuration:配置 Bean@Bean 注解@ComponentScan 注解Spring 工厂创建对象的多种方式整合多个配置信息四维一体的开发纯注解版AOP编程 …纯注解版 Spring + Mybatis 整合 …纯注解版事务编程YML 简介
简单对象:直接能够通过 new 方式创建的对象
  • User、UserService、UserDAO
复杂对象:不能通过 new 的方式直接创建的对象
  • Connection、SqlSessionFactory

@Bean

注解创建复杂对象的注意事项:遗留系统整合

@Bean
public Connection conn1() {
	Connection conn = null;
	try {
		ConnectionFactoryBean factoryBean = new ConnectionFactoryBean();
		conn = factoryBean.getObject();
	} catch (Exception e) {
		e.printStackTrace();
	}
	return conn;
}
           

@Bean

注解创建对象,自定义 id 值

@Bean

注解创建对象,控制对象创建次数

@Bean
@Scope("singleton|prototype") // 默认值 singleton
           

@Bean 注解的注入与细节

用户自定义类型:

@Bean
public UserDAO userDAO() {
	return new UserDAOImpl();
}

@Bean
public UserService userService(UserDAO userDAO) {
	UserServiceImpl userService = new UserServiceImpl();
	userService.setUserDAO(userDAO);
	return userService;
	
//简化写法
@Bean
public UserService userService() {
	UserServiceImpl userService = new UserServiceImpl();
	userService.setUserDAO(userDAO());
	return userService;
}
           

JDK类型:

@Bean
public Customer customer() {
	Customer customer = new Customer();
	customer.setId(1);
	customer.setName("xiaohei");
	
	return customer;
}
           

如果直接在代码中进行 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;
	}
}
           

@ComponentScan 注解

@ComponentScan

注解在配置 bean 中进行使用,等同于 XML 配置文件中的

<context:component-scan>

标签

目的:进行相关注解的扫描(

@Component

@Value

@Autowired

…)

基本使用:

  • XML 方式:
  • 注解方式:
@Configuration
@ComponentScan(basePackages = "com.yusael.scan")
public class AppConfig2 {
}
           

排除策略的的使用:

  • XML 方式:
<context:component-scan base-package="com.yusael">
	<context:exclude-filter type="assignable" expression="com.yusael.bean.User"/>
</context:component-scan>
           
  • 注解方式:

    排除特定的注解:

    type = FilterType.ANNOTATION, value={}

    排除特定的类型:

    type = FilterType.ASSIGNABLE_TYPE , value={]

    切入点表达式:

    type = FilterType.ASPECTJ, pattern=""

    正则表达式:

    type = FilterType.REGEX, pattern=""

    自定义排除策略:

    type = FilterType.CUSTOM, pattern=""

@ComponentScan(basePackages = "com.yusael.scan",
               excludeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION, value={Service.class}),
                                 @ComponentScan.Filter(type= FilterType.ASPECTJ, pattern = "*..User1")})
           

包含策略的使用:

  • XML 方式:
<context:component-scan base-package="com.yusael" use-default-filters="false">
	<context:include-filter type="" expression=""/>
</context:component-scan>
           
  • 注解方式:参数与排除策略中一样
@ComponentScan(basePackages = "com.yusaael.scan",
               useDefaultFilters = false,
               includeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value={Service.class})})
           

Spring 工厂创建对象的多种方式

多种配置方式的应用场景:

【Spring 高级注解】@Configuration、@Bean、@ComponentScan@Configuration:配置 Bean@Bean 注解@ComponentScan 注解Spring 工厂创建对象的多种方式整合多个配置信息四维一体的开发纯注解版AOP编程 …纯注解版 Spring + Mybatis 整合 …纯注解版事务编程YML 简介

配置优先级:

@Component

及其衍生注解 <

@Bean

< 配置文件

<bean>

标签

  • 优先级高的配置,会覆盖优先级低配置
  • 配置覆盖:id 值需要保持一致
@Component
public class User{
}

@Bean
public User user(){
  return new User();
}

<bean id="user" class="xxx.User"/>
           

通过配置优先级,可以解决基于注解进行配置的耦合问题:

@Configuration
//@ImportResource("applicationContext.xml")
public class AppConfig4 {

    @Bean
    public UserDAO userDAO() {
        return new UserDAOImpl();
    }
}

@Configuration
@ImportResource("applicationContext.xml")
public class AppConfig5{
  
}

applicationContext.xml
<bean id="userDAO" class="com.baizhiedu.injection.UserDAOImplNew"/>
           

整合多个配置信息

为什么会有多个配置信息?

  • 拆分多个配置 bean 的开发,是一种模块化开发的形式,也体现了面向对象各司其职的设计思想

多配置信息整合的方式:

  • 多个配置 Bean 的整合
  • 配置 Bean 与

    @Component

    相关注解的整合
  • 配置 Bean 与 SpringXML 配置文件的整合

整合多种配置需要关注那些要点:

  • 如何使多配置的信息汇总成一个整体
  • 如何实现跨配置的注入

多个配置 Bean 的整合

多配置的信息汇总:

  1. 基于

    basePackegs

    包扫描的方式整合多个配置 Bean
    【Spring 高级注解】@Configuration、@Bean、@ComponentScan@Configuration:配置 Bean@Bean 注解@ComponentScan 注解Spring 工厂创建对象的多种方式整合多个配置信息四维一体的开发纯注解版AOP编程 …纯注解版 Spring + Mybatis 整合 …纯注解版事务编程YML 简介
  2. @Import

    在一个配置 Bean 中引入另一个配置 Bean
    【Spring 高级注解】@Configuration、@Bean、@ComponentScan@Configuration:配置 Bean@Bean 注解@ComponentScan 注解Spring 工厂创建对象的多种方式整合多个配置信息四维一体的开发纯注解版AOP编程 …纯注解版 Spring + Mybatis 整合 …纯注解版事务编程YML 简介
  3. 在工厂创建时,指定多个配置 Bean 的 Class 对象【了解】
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig1.class, AppConfig2.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;
    }
}

@Configuration
public class AppConfig2 {

    @Bean
    public UserDAO userDAO() {
        return new UserDAOImpl();
    }
}
           

配置 Bean 与 @Component 相关注解的整合

@Component(@Repository)
public class UserDAOImpl implements UserDAO{
}

@Configuration
@ComponentScan("")
public class AppConfig3 {
   
    @Autowired
    private UserDAO userDAO;

    @Bean
    public UserService userService() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDAO(userDAO);
        return userService;
    }
}

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig3.class);
           

配置 Bean 与配置文件整合

主要用于:

  1. 遗留系统的整合
  2. 配置覆盖
public class UserDAOImpl implements UserDAO{
}
<bean id="userDAO" class="com.baizhiedu.injection.UserDAOImpl"/>

@Configuration
@ImportResource("applicationContext.xml")
public class AppConfig4 {
  
    @Autowired
    private UserDAO userDAO;

    @Bean
    public UserService userService() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDAO(userDAO);
        return userService;
    }
}

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig4.class);
           

配置 Bean 底层实现原理

Spring 在配置 Bean 中加入了

@Configuration

注解后,底层就会通过 Cglib 的代理方式,来进行对象相关的配置、处理

【Spring 高级注解】@Configuration、@Bean、@ComponentScan@Configuration:配置 Bean@Bean 注解@ComponentScan 注解Spring 工厂创建对象的多种方式整合多个配置信息四维一体的开发纯注解版AOP编程 …纯注解版 Spring + Mybatis 整合 …纯注解版事务编程YML 简介

四维一体的开发

什么是四维一体?

Spring开发一个功能的4种形式,虽然开发方式不同,但是最终效果是一样的。

  1. 基于schema
  2. 基于特定功能注解
  3. 基于原始<bean
  4. 基于@Bean注解

案例:

1. <context:property-placehoder
2. @PropertySource  【推荐】
3. <bean id="" class="PropertySourcePlaceholderConfigure"/>
4. @Bean            【推荐】
           

纯注解版AOP编程 …

纯注解版 Spring + Mybatis 整合 …

纯注解版事务编程

1. 原始对象 XXXService
   <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
     <property name="userDAO" ref="userDAO"/>
   </bean>

   @Service
   public class UserServiceImpl implements UserService{
         @Autowired
         private UserDAO userDAO;
   }

2. 额外功能
   <!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"/>
    </bean>
    
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource){
          DataSourceTransactionManager dstm = new DataSourceTransactionManager();
          dstm.setDataSource(dataSource);
          return dstm 
    }

3. 事务属性
    @Transactional
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDAO userDAO;

4. 基于Schema的事务配置 
   <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
   @EnableTransactionManager ---> 配置Bean
           

YML 简介

YML(YAML) 是一种新形式的配置文件,比 XML 更简单,比 Properties 更强大。

YAML is a nice human-readable format for configuration, and it has some useful hierarchical properties. It’s more or less a superset of JSON, so it has a lot of similar features.

Properties 进行配置的问题:

  1. Properties 表达过于繁琐,无法表达数据的内在联系
  2. Properties 无法表达对象、集合类型

YML 语法简介:

1. 定义yml文件 
   xxx.yml xxx.yaml
2. 语法
   1. 基本语法
      name: suns
      password: 123456
   2. 对象概念 
      account: 
         id: 1
         password: 123456
   3. 定义集合 
      service: 
         - 11111
         - 22222