spring注解开发,ioc和id

  1. 给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id。
  2. @Configuration
  3. @Bean(“name”)设置id
  4. @ComponentScan({“com.chen”})
    1. excludeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class,Service.class})};排除
    2. includeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class})} 包含
    3. @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={TxConfig.class,UserDao.class,UserService.class}),查找具体的类
    4. @Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class});自定义过滤器
  5. @ComponentScans
    1. Value是ComponentScan数组
  6. @Scope
    1. prototype:多实例,ioc容器启动并不会去调用方法创建对象到容器,只有获取时才创建。
    2. singleton:ioc容器启动会调用方法创建对象放到ioc容器中;以后没吃获取都从容器中拿
    3. request
    4. session
  7. 懒加载;@Lazy
    1. 单实例bean,默认在容器启动的时候创建对象;
    2. 懒加载:容器启动时不创建对象,获取bean时创建对象
  8. @Conditional({Condition}):按照一定的条件进行判断,满足条件给容器中注册bean
    1. 放在方法上
    2. 自定义一个类实现Condition接口

/**

     * ConditionContext:判断条件,能使用的上下文

     * AnnotatedTypeMetadata:注解信息

     */

    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

       //判断是否是linux系统

       //1.获取到ioc使用的beanfactory

       ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

       //2.获取类加载器

       ClassLoader classLoader = context.getClassLoader();

       //3.获取当前环境信息

       Environment environment = context.getEnvironment();

       //4.获取bean定义的注册类

       BeanDefinitionRegistry registry = context.getRegistry();

      

       //可以判断容器中的bean注册情况,也可以给容器中注册bean

       boolean definition = registry.containsBeanDefinition("person");

      

      

       String pString = environment.getProperty("os.name");

       if(pString.contains("linux")){

           return true;

       }

       return false;

    }

  1. @Conditional放在配置类上,满足当前条件,这个类中配置的所有bean注册才能生效
  2. 给容器中注册组件
    1. 包扫描+组件标注注解(@Controller,@Service,@Component)
    2. @Bean[导入的第三方包里面的组件]
    3. @Import[快速给容器中导入一个组件]
  3. @Import:快速导入组件,id默认时组件全类名
    1. @Import({Color.class,Red.class})
    2. ImportSelector:返回需要导入的组件的全类名数组

/**

*@author  chenmin

*@version 创建时间:2020年8月27日 下午4:06:10

*AnnotationMetadata:当前标注@Import注解的类上所有注解信息

*

*/

public class MyImportSelector implements ImportSelector {

 

       //返回值,就是到导入到容器中的组件全类名

       public String[] selectImports(AnnotationMetadata importingClassMetadata) {

             

              return new String[]{"com.chen.bean.Blue","com.chen.bean.Yellow"};

       }

 

}

    1. ImportBeanDefinitionRegistrar

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{

 

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

      

       boolean definition = registry.containsBeanDefinition("com.chen.bean.Red");

       boolean definition2 = registry.containsBeanDefinition("com.chen.bean.Blue");

      

       if(definition && definition2){

           //指定bean

           RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);

           registry.registerBeanDefinition("rainBow", rootBeanDefinition);

       }

    }

 

}

  1. 使用spring提供的FactoryBean接口
  2. Bean创建---初始化---销毁的过程
    1. 容器管理bean的生命周期:我们可以自定义初始化和销毁方法
    2. 构造(对象创建)
      1. 单实例:在容器启动的时候创建bean
      2. 多实例:在每次获取的时候创建bean
    3. 指定初始化和销毁方法

@Bean(initMethod="init",destroyMethod="destory")

       public Car car(){

              return new Car();

       }

    1. 初始化:对象完成创建,并赋值,调用初始化方法
    2. 销毁
      1. 单实例:容器关闭,调用销毁方法
      2. 多实例:容器关闭,容器不会管理bean,容器不会调用销毁方法
    3.  
  1. 通过Bean实现InititalizingBean接口来定义初始化,DisposableBean接口实现销毁

public class Cat implements InitializingBean,DisposableBean{

 

      

       public Cat() {

              System.out.println("cat....constructor....");

       }

 

       public void destroy() throws Exception {

              System.out.println("cat....destory....");

       }

 

       public void afterPropertiesSet() throws Exception {

              System.out.println("cat....afterPropertiesSet....");

       }

}

  1. 使用JSR250
    1. @PostConstruct,初始化,在bean创建完成并且属性赋值完成,来执行初始化方法

@PostConstruct

       public void init(){

              System.out.println("dog....init....");

       }

    1. @PreDestory,销毁,在容器销毁bean之前,通知销毁

@PreDestory

       public void destory(){

              System.out.println("dog....destory....");

       }

  1. BeanPostProcessor接口,bean的后置处理器,在bean初始化前后进行一些处理工作
    1. populateBean(beanName,mbd,instanceWrapper);给属性赋值
    2. 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization

spring注解开发,ioc和id_第1张图片

 

spring注解开发,ioc和id_第2张图片

 

spring注解开发,ioc和id_第3张图片

 

    1. postProcessBeforeInitialization
    2. invokeInitMethods(beanName, wrappedBean, mb;初始化方法
    3. postProcessAfterInitialization
  1. @Value
    1. 基本数值:
    2. 可以写SpEL,#{20-2}
    3. ${},取出配置文件中的值(在运行环境)

spring注解开发,ioc和id_第4张图片

${}配合@PropertySource("classpath:person.properties")使用,该注解放在配置类上

  1. 自动装配
    1. Spring利用依赖注入(DI)完成对IOC容器中各个组件的依赖关系赋值
    2. @Autowired,自动注入
      1. 默认优先按照类型去容器中找对应的组件
      2. 如果找到多个相同类型组件,再将属性的名称作为组件id去容器中查找
    3. @Qualifier("bookDao")

使用指定装配的组件id,而不是使用属性名。如下图

    1. @Autowired自动装配默认一定要将属性赋值好,没有就会报错,设置@Autowired(required=false),这样就不会报错了。
    2. @Primary:让spring进行自动装配的时候,默认使用首选的bean,首选使用bookDao2,如下图:

spring注解开发,ioc和id_第5张图片

    1. 也可以继续使用@Qualifier(“bookDao”)指定装配
    2. Spring还支持@Resource(JSR250)和@Inject(JSR330)java规范注解
      1. @Resource:按照组件的名称进行装配
      2. @Inject:可以和@Primary结合使用,但要导入javax.inject这个包,和@Autowired一样
    3. @Autowired可以标注构造器,方法,属性参数;标在构造器上:如果组件只有一个参数构造器,这个有参构造器@Autowired可以省略,参数位置的组件可以从容器中获取
  1. 自定义组件想要使用spring容器底层的一些组件(ApplicationContext,BeanFactory)自定义组件实现xxxAware.
  2. @Profile
    1. 指定组件在那个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
    2. 加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中,默认是default环境
    3. @Profile可以加在配置类上,也可以在注册方法上
    4. 手动修改运行环境:

spring注解开发,ioc和id_第6张图片

 

  1. 声明式事务
    1. 环境搭建

1.导入相关依赖

              数据源,数据库驱动,spring-jdbc

 

2.配置数据源,jdbcTemplate操作数据库

3.给方法上标注@Transactional注解

4.给配置类标注@EnableTransactionManagement

       5.将事务管理器添加到容器中

    1. 原理

1.@EnableTransactionManagement

*      利用TransactionManagementConfigurationSelector给容器中注入两个组件:

*      AutoProxyRegistrar,ProxyTransactionManagementConfiguration

*      1.AutoProxyRegistrar

*             给容器中注册一个InfrastructureAdvisorAutoProxyCreator组件

*             分析InfrastructureAdvisorAutoProxyCreator该类的作用

*             利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器)

*

*      2.ProxyTransactionManagementConfiguration

*             给容器中注册事务增强器

*                    1.事务增强器要用事务注解信息,TransactionAttributeSource解析事务注解

*                    2.事务拦截器:

*                           TransactionInterceptor;保存了事务属性信息,事务管理器

*                           它是一个MethodInterceptor

*                           在目标方法执行的时候:

*                                  执行拦截器链

*                                  事务拦截器:

*                                         1.获取事务属性

*                                         2.获取PlatormTransctionManager

    1. 代码

spring注解开发,ioc和id_第7张图片

配置数据源和事务管理器:

 

@EnableTransactionManagement
@ComponentScan("com.chen.tx")
@Configuration
public class TxConfig {

    @Bean
    public DataSource dataSource() throws Exception{
        
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser("root");
        dataSource.setPassword("root");
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        
        return dataSource;
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate() throws Exception{
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }
    
    //事务管理器
    @Bean
    public PlatformTransactionManager platformTransactionManager() throws Exception{
        PlatformTransactionManager platformTransactionManager = new DataSourceTransactionManager(dataSource());
        return platformTransactionManager;
    }
}

你可能感兴趣的:(spring)