Spring的高级注解

一、配置Bean @Configuration

Spring在3.x提供的注解,用于替换XML配置文件。

@Configuration
public class AppConfig{

}

AnnotationConfigApplicationContext

1.创建工厂代码
   ApplicationContext app = new AnnotationConfigApplicationContext();
2.指定配置文件
   1.指定配置bean的Class
       ApplicationContext app = new AnnotationConfigApplicationContext(AppConfig.class);
   2.指定配置bean所在的路径
       ApplicationContext app = new AnnotationConfigApplicationContext(“com.bao.bean”);

配置Bean开发的细节分析

1.基于注解开发使用日志

不能集成Log4j,取而代之的是logback。
引入相关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.10</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.10</version>
        </dependency>
        <dependency>
            <groupId>org.logback-extensions</groupId>
            <artifactId>logback-ext-spring</artifactId>
            <version>0.1.4</version>
        </dependency>
引入logback配置文件:
    logback.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{yyyy-MM-dd' 'HH:mm:ss.sss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>

        <root level="DEBUG">
            <appender-ref ref="STDOUT" />
        </root>
    </configuration>

2.@Configuration注解的本质

本质:也是@Component注解的衍生注解
也可以应用<context:component-scan>进行扫描

二、@Bean注解

@Bean注解在配置bean中进行使用,等同于XML配置文件中的<bean>标签

1.@Bean注解的基本使用

对象的创建

1.简单对象
  可以直接new的对象
2.复杂对象
  不可直接new的对象

@Bean注解创建复杂对象的注意事项

FactoryBean与@Bean的联合使用(遗留系统整合)

public class ConnectionFactoryBean implements FactoryBean<Connection> {
    public Connection getObject() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useSSL=false","root","123456");

        return conn;
    }
    public Class<?> getObjectType() {
        return Connection.class;
    }
    public boolean isSingleton() {
        return false;
    }
}

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

自定义id值

@Bean("u")

控制对象的创建次数

@Bean
@Scope("singleton|prototype")

2.@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(50);
        customer.setName("李星云");
        return customer;
    }
    
    引入properties配置文件解决耦合:
    init.properties:
       id = 50
       name = 李星云
    
    @Configuration
    @PropertySource(value = "classpath:init.properties",encoding = "UTF-8")
    public class AppConfig1 {
        @Value("${id}")
        private int id;
        @Value("${name}")
        private String name;

3.@ComponentScan注解

@ComponentScan注解在配置bean中进行使用,等同于xml配置文件中的<context:component-scan>标签

目的:进行相关注解扫描

基本使用

@Configuration
@ComponentScan(basePackages = "com.bao.scan")
public class AppConfig2 {
}
​
等价于<context:component-scan base-package=""/>

排除、包含是使用(五种type类型,见基础注解)

排除(可叠加):

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

type = FilterType.ANNOTATION          value
                 .ASSIGNABLE_TYPE        value
                 .ASPECTJ                          pattern
                 .REGEX                             pattern
                 .CUSTOM                         value

包含(可叠加):

@Configuration
@ComponentScan(basePackages = "com.bao.scan",
        includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class}),
                          @ComponentScan.Filter(type = FilterType.ASPECTJ,pattern = {"com.bao..*"})}})
public class AppConfig2 {
}
​
type = FilterType.ANNOTATION           value
                 .ASSIGNABLE_TYPE      value
                 .ASPECTJ              pattern
                 .REGEX                pattern
                 .CUSTOM               value

4.Spring工厂创建对象的多种配置方式

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

@Component及其衍生注解       程序员自己开发的类型
@Bean                       框架提供的类型,其他程序员开发的类型(没有源码)
<bean id="user" class=""/>  纯注解开发基本不用,遗留系统整合使用
@Import                     1.Spring框架底层使用 2.多配置Bean整合

配置优先级

@Component及其衍生注解 < @Bean < <bean id="user" class=""/>
优先级高的配置 覆盖优先级低配置
​
@ComponentScan与配置文件<bean>标签整合
           ---->@ImportResource("applicationContext.xml")
                覆盖,可以解决基于注解进行配置的耦合问题

5.多个配置Bean的整合

⚪多配置的信息汇总

base-package进行多个配置Bean的整合

@Configuration
public class AppConfig1 {
    @Bean
    public UserService userService(){
        UserServiceImpl userService = new UserServiceImpl();
        return userService;
    }
}

@Configuration
public class AppConfig2 {
    @Bean
    public UserDAO userDAO(){
        UserDAOImpl userDAO = new UserDAOImpl();
        return userDAO;
    }
}

ApplicationContext app = new AnnotationConfigApplicationContext("com.bao.config");
UserDAO userDAO = (UserDAO) app.getBean("userDAO");
UserService userService = (UserService) app.getBean("userService");

@import进行多个配置Bean的整合

@Configuration
@Import(AppConfig2.class)
public class AppConfig1 {
    @Bean
    public UserService userService(){
        UserServiceImpl userService = new UserServiceImpl();
        return userService;
    }
}

ApplicationContext app = new AnnotationConfigApplicationContext(com.bao.config.AppConfig1.class);
UserDAO userDAO = (UserDAO) app.getBean("userDAO");
UserService userService = (UserService) app.getBean("userService");
System.out.println(userDAO);
System.out.println(userService);

在工厂创建时,指定多个配置Bean的Class对象

ApplicationContext app = 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;
    }
}

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

@Component
public class UserDAOImpl implements UserDAO{

}

@Configuration
@ComponentScan(basePackages = "com.bao.injection)
public class AppConfig3 {
    @Bean
    public UserService userService(){
        UserServiceImpl userService = new UserServiceImpl();
        return userService;
    }
}

ApplicationContext app = new AnnotationConfigApplicationContext(AppConfig3.class);
UserDAO userDAO = (UserDAO) app.getBean("userDAOImpl");

配置Bean与配置文件整合

1.遗留系统整合 2.配置覆盖

public class UserDAOImpl implements UserDAO{

}
applicationContext.xml:
<bean id="userDAO" class="com.bao.injection.UserDAOImpl"/>

@Configuration
@ImportResource("applicationContext.xml")
public class AppConfig4 {
    @Bean
    public UserService userService(){
        UserServiceImpl userService = new UserServiceImpl();
        return userService;
    }

6.配置Bean底层实现原理

@Configuration
实际上AOP方式进行开发(cglib)

7.四维一体的开发思想

1.什么是四维一体

Spring开发一个功能的4种形式,虽然开发方式不同,但是最终效果是一样的。
1.基于schema  <context:
2.基于特定功能注解
3.基于原始<bean>
  <bean id="pro" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="location" value="classpath:init.properties"/>
  </bean>
4.基于@Bean注解

2.四维一体开发案例

<context:property-placehoder
@PeopertySource  [推荐]
<bean id="" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
@Bean            [推荐]

8.纯注解版AOP编程

搭建环境

1.应用配置Bean   @Configuration
2.注解扫描       @ComponentScan("basePackages = "com.bao.injection"")

开发步骤

1.原始对象
  @Service
  public class UserServiceImpl implements UserService{
  
  }
2.创建切面类  (额外功能 切入点 组装切面)
  @Aspect
  @Component
  public class MyAspect {
    @Around("execution(* login(..))")//切入点
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("---切面类log---");
        Object ret = joinPoint.proceed();//原始方法运行
        return ret;
      }
  }
3.Spring配置文件中
  //<aop:aspectj-autoproxy />
  @EnableAspectjAutoProxy
  
  @Configuration
  @ComponentScan(basePackages = "com.bao.aop")
  @EnableAspectjAutoProxy
  public class AppConfig{
      
  }

注解AOP细节分析

1.代理创建方式的切换 JDK Cglib
  <aop:aspectj-autoproxy proxy-target-class=true|false />
  
  @EnableAspectjAutoProxy(proxyTargetClass = true|false)
2.SpringBoot  AOP开发方式
  //@EnableAspectjAutoProxy 默认设置好了
  
  1.原始对象
  @Service
  public class UserServiceImpl implements UserService{
  
  }
  2.创建切面类  (额外功能 切入点 组装切面)
  @Aspect
  @Component
  public class MyAspect {
    @Around("execution(* login(..))")//切入点
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("---切面类log---");
        Object ret = joinPoint.proceed();//原始方法运行
        return ret;
      }
  }

  Spring      AOP代理默认实现  JDK
  SpringBOOT  AOP代理默认实现  Cglib

9.纯注解Spring+MyBatis整合

基础配置(配置Bean)

spring配置文件回顾:
配置文件(ApplicationContext.xml)进行相关配置
     <bean id="dataSource" class=""/>
  创建SqlSessionFactory:
     <bean id="ssfb" class="SqlSessionFactoryBean">
           <property name="dataSource" ref=""/>
           <property name="typeAliasesPackage">
                指定  实体类所在的包
           </property>
           <property name="mapperLocations">
                指定  映射文件的路径  还有通用配置
                com.bao,maooer/*Mapper.xml
           </property>
     </bean>
     
   DAO接口的实现类:
     <bean id="scanner" class="MapperScannerConfigure">
           <property name="SqlSessionFactoryBeanName" value="ssfb"/>
           <property name="basePacakge">
                 指定 DAO接口放置的包 
           </property>
     </bean>
------------------------------------------------------------------------

1.连接池
  @Bean
  public DruidDataSource dataSource(){
      DriidDataSource dataSource = new DruidDataSource();
      dataSource.setDriverClassName("");
      dataSource.setUrl();
      dataSource.setUsername();
      dataSource.setPassword();
      
      return dataSource;
  }
  
2.SqlSessionFactoryBean
  @Bean
  public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
       SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setTypeAliasesPackage("com.bao.mybatis");
        
        //设置Mapper文件路径
        //sqlSessionFactoryBean.setMapperLocations(new ClassPathResource[]{new ClassPathResource("*Mapper.xml")});
       try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources("classpath*:*Mapper.xml");
            sqlSessionFactoryBean.setMapperLocations(resources);
        } catch (IOException e) {
            e.printStackTrace();
        } 
        
        return sqlSessionFactoryBean;
  }
  
3.MapperScannerConfigure
@MapperScan(basePackage={"com.bao.dao"})  --->配置bean

编码:

1.实体
  public class User implements Serializable {
    private int id;
    private String name;
    private String password;

    public User() {
    }

    public User(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

2.表(略)
3.DAO接口
  public interface UserDAO {
    public void save(User user);
 }
 
4.Mapper文件
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper namespace="com.bao.mybatis.UserDAO">
      <insert id="save" parameterType="User">
        insert into t_users(name,password) values (#{name},#{password})
      </insert>
      <delete id="delete" parameterType="User">
        delete from t_users where id=#{id}
      </delete>
  </mapper>

配置Bean注解耦合

driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mybatis?useSSL=false
username = root
password = 123456
typeAliasesPackage = com.bao.mybatis
mapperLocations = classpath*:com.bao.mapper/*Mapper.xml

@Component
@PropertySource(value = "classpath:init.properties",encoding = "UTF-8")
public class MybatisProperties {
    @Value("${driverClassName}")
    private String driverClassName;
    @Value("${url}")
    private String url;
    @Value("${username}")
    private String username;
    @Value("${password}")
    private String password;
    @Value("${typeAliasesPackage}")
    private String typeAliasesPackage;
    @Value("${mapperLocations}")
    private String mapperLocations;

//配置Bean注入
@Configuration
@ComponentScan(basePackages = "com.bao.mybatis")
@MapperScan(basePackages = "com.bao.mybatis")
public class MybatisAutoConfiguration {
    @Autowired
    private MybatisProperties mybatisProperties;
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(mybatisProperties.getDriverClassName());
        dataSource.setUrl(mybatisProperties.getUrl());
        dataSource.setUsername(mybatisProperties.getUsername());
        dataSource.setPassword(mybatisProperties.getPassword());
        return dataSource;
    }
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
        //sqlSessionFactoryBean.setMapperLocations(new ClassPathResource[]{new ClassPathResource("UserDAOMapper.xml")});
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(mybatisProperties.getMapperLocations());
            sqlSessionFactoryBean.setMapperLocations(resources);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSessionFactoryBean;
    }
}

10.纯注解的事务编程

1.原始对象  XXXService
    <bean id="userService" class="com.bao.mybatis.service.UserServiceImpl">
    <!--注入DAO,ref="userDAO"源自于MapperScannerConfigure-->
        <property name="userDAO" ref="userDAO"></property>
    </bean>
    -----------------------------------------------------------------------
    @Service
    public class UserServiceImpl implements UserService{
          @Autowired
          private UserDAO userDAO;
    }
    
2.额外功能
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <!--        注入连接池-->
        <property name="dataSource" ref="dataSource"></property>
    </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"></tx:annotation-driven>
  -----------------------------------------------------------------------
  @EnableTransactionManager  //配置Bean中完成  自动扫描dataSourceTransactionManager

Spring框架中YML的使用

什么是YML

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

Properties进行配置问题

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

YML语法简介

1.定义yml文件
  xxx.yml   xxx.yaml

2.语法
  1.基本语法
    name:chenbao
    password:1234
    
  2.对象概念
    accout:
        id:1
        password:1234
  3.定义集合
    service:
        - 111
        - 222

Spring与YML集成思路分析

Spring提供的 YamlPropertiesFactoryBean  读取  YML
1.准备yml配置文件
  init.yml
    name:chen
    password:1234
2.读取yml  转换成 Properties
  YamlPropertiesFactoryBean.setResources(yml配置文件路径) new ClassPathResource();
  YamlPropertiesFactoryBean.getObject();  --->返回Properties
3.应用PropertySourcePlaceholderConfigurer.setProperties();
4.类中应用@Value注解注入

Spring与YML集成编码

环境搭建

<dependency>
   <groupId>org.yaml</groupId>
   <artifactId>snakeyaml</artifactId>
   <version>1.26</version>
</dependency>
最低版本 1.18

编码

1.准备yml配置文件
  chen:
    name: chenbao
    password: 1234
    
2.配置Bean中操作  完成YAML读取  与  PropertySourcePlaceholaerConfigure的创建
  @Configuration
  @ComponentScan(basePackages = "com.bao.yml")
  public class YmlAutoConfiguration {
      @Bean
      public PropertySourcesPlaceholderConfigurer configurer(){
          YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
          yamlPropertiesFactoryBean.setResources(new ClassPathResource("init.yml"));
          Properties properties = yamlPropertiesFactoryBean.getObject();

          PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
          configurer.setProperties(properties);
          return configurer;
      }
  }

3.类 加入 @Value注解
  @Component
  public class Account {
      @Value("${chen.name}")
      private String name;
      @Value("${chen.password}")
      private String password;
      
Test:
public void test3(){
        ApplicationContext app = new AnnotationConfigApplicationContext(YmlAutoConfiguration.class);
        Account account = (Account) app.getBean("account");
        System.out.println(account.getName());
        System.out.println(account.getPassword());
    }

Spring与YML集成的问题

1.集合处理的问题
  SpringEL表达式解决:
    list: 111,222
    @Value("#{'${list}'.split(',')}")
    private List<String> list;
    
2.对象类型的YAML进行配置时  过于繁琐
  @Value("${chen.name}")和@Value("${chen.password}")
  
  解决:SpringBooT--->@ConfigurationProperties
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值