• Spring开发2 spring基础及组件使用2(conditional,import,factorybean)


    JDO  java data object  99-03年 

    注解:

    • 声明配置类 bean 早期从xml解析 配置类
    • @configuration  相当于 配置文件

    扫描的注解: @controller  @Service @Respostry @Component

    if(useDefaultFilters){

    registerDefaultFilters();

    }

    this.includeFilters.add(new AnnotationTypeFilter(Componet.class))

    以@Component--->

    com.enjoy.cpa2

    @Controller

    @Component

    @Service

    IOC就是对我们Bean进行管理:bean 注册 实例化 管理

    @Conditional条件注册bean

    根据指定条件选择性地注册bean实例

     1 package com.enjoy.cap5.config;
     2 
     3 
     4 import com.enjoy.cap1.Person;
     5 import org.springframework.context.annotation.Bean;
     6 import org.springframework.context.annotation.Configuration;
     7 
     8 
     9 @Configuration
    10 public class Cap5MainConfig {
    11 
    12     @Bean("person")  // Bean的id 不设置id的时候,默认取的是方法名
    13     public Person person(){
    14         System.out.println("给容器中添加person....");
    15         return new Person("person", 20);
    16     }
    17 
    18     @Bean("lison")
    19     public Person lison(){
    20         System.out.println("给容器中添加lison....");
    21         return new Person("Lison", 20);
    22     }
    23 
    24     @Bean("james")  // bean在容器中的ID为james,IOC容器MAP  map.put("id", value);
    25     public Person james(){
    26         System.out.println("给容器中添加james....");
    27         return new Person("james", 20);
    28     }
    29 
    30     // 创建的时候就会把bean map.put到容器当中
    31 
    32 }
     1 import com.enjoy.cap5.config.Cap5MainConfig;
     2 import org.junit.Test;
     3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
     4 
     5 public class Cap5Test {
     6 
     7     @Test
     8     public void test01(){
     9         // 创建容器将bean加载进来
    10         AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap5MainConfig.class);
    11 
    12         System.out.println("IOC容器创建完成........");
    13 
    14     }
    15 }

    需求:测试运行时候,如果操作系统是windows,就让Lison这个对象实例化到容器中,如果是LINUX,就是让james实例化到容器中。

    实现条件

    beanFactory

    FactoryBean  和 BeanFactory 的区别

    • FactoryBean:可以把java实例bean通过FactoryBean注入到容器中
    • BeanFactory:从容器中获取实例化后的bean
     1 package com.enjoy.cap5.config;
     2 
     3 
     4 import com.enjoy.cap1.Person;
     5 import org.springframework.context.annotation.Bean;
     6 import org.springframework.context.annotation.Conditional;
     7 import org.springframework.context.annotation.Configuration;
     8 
     9 
    10 @Configuration
    11 public class Cap5MainConfig {
    12 
    13     @Bean("person")  // Bean的id 不设置id的时候,默认取的是方法名
    14     public Person person(){
    15         System.out.println("给容器中添加person....");
    16         return new Person("person", 20);
    17     }
    18 
    19     @Conditional(WinCondition.class)
    20     @Bean("lison")
    21     public Person lison(){
    22         System.out.println("给容器中添加lison....");
    23         return new Person("Lison", 20);
    24     }
    25 
    26     @Conditional(LinCondition.class)
    27     @Bean("james")  // bean在容器中的ID为james,IOC容器MAP  map.put("id", value);
    28     public Person james(){
    29         System.out.println("给容器中添加james....");
    30         return new Person("james", 20);
    31     }
    32 
    33     // 创建的时候就会把bean map.put到容器当中
    34 
    35 }
     1 package com.enjoy.cap5.config;
     2 
     3 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
     4 import org.springframework.context.annotation.Condition;
     5 import org.springframework.context.annotation.ConditionContext;
     6 import org.springframework.core.env.Environment;
     7 import org.springframework.core.type.AnnotatedTypeMetadata;
     8 
     9 public class LinCondition implements Condition {
    10     /**
    11      * ConditionContext:判断条件可以使用的上下文(环境)
    12      * AnnotatedTypeMetadata:注解的信息
    13      * */
    14     public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
    15         // TODO >> 是否为Windows
    16         // 能够获取到IOC容器正在使用的beanFactory
    17         ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
    18         // 获取当前环境变量(包括当前操作系统是win还是linux)
    19         Environment environment = conditionContext.getEnvironment();
    20         String os_name = environment.getProperty("os.name");
    21         System.out.println(os_name);
    22 
    23         if(os_name.contains("linux")){
    24             return true;
    25         }
    26         return false;  // 返回false不起任何作用
    27     }
    28 }
     1 package com.enjoy.cap5.config;
     2 
     3 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
     4 import org.springframework.context.annotation.Condition;
     5 import org.springframework.context.annotation.ConditionContext;
     6 import org.springframework.core.env.Environment;
     7 import org.springframework.core.type.AnnotatedTypeMetadata;
     8 
     9 public class WinCondition implements Condition {
    10     /**
    11      * ConditionContext:判断条件可以使用的上下文(环境)
    12      * AnnotatedTypeMetadata:注解的信息
    13      * */
    14     public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
    15         // TODO >> 是否为Windows
    16         // 能够获取到IOC容器正在使用的beanFactory
    17         ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
    18         // 获取当前环境变量(包括当前操作系统是win还是linux)
    19         Environment environment = conditionContext.getEnvironment();
    20         String os_name = environment.getProperty("os.name");
    21         System.out.println(os_name);
    22 
    23         if(os_name.contains("Windows")){
    24             return true;
    25         }
    26         return false;  // 返回false不起任何作用
    27     }
    28 }

    Mac OS X
    Mac OS X
    给容器中添加person....
    IOC容器创建完成........

    @Import注册bean

    1,手动添加组件到IOC容器;

    2,使用ImportSelector自定义返回组件

    3, 使用ImportBeanDefinitionRegistrar返回自定义组件

     1 package com.enjoy.cap6.config;
     2 
     3 
     4 import com.enjoy.cap1.Person;
     5 import com.enjoy.cap6.bean.Cat;
     6 import com.enjoy.cap6.bean.Dog;
     7 import org.springframework.context.annotation.Bean;
     8 import org.springframework.context.annotation.Configuration;
     9 import org.springframework.context.annotation.Import;
    10 
    11 
    12 @Configuration
    13 @Import(value={Dog.class, Cat.class, JamesImportSelector.class})  // 相当与new一个对象放到容器中
    14 
    15 public class Cap6MainConfig {
    16 
    17    /**
    18     * 给我们容器中注册组件:
    19     * 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用
    20     * 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个
    21     * 3.@import:[快速给容器导入一个组件]  注意:@Bean有点简单
    22     *      a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id)
    23     *      b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
    24     */
    25     // 容器启动时初始化person的bean实例
    26     @Bean("person")
    27     public Person person(){
    28         System.out.println("给容器中添加person....");
    29         return new Person("person", 20);
    30     }
    31 
    32 }
     1 package com.enjoy.cap6.config;
     2 
     3 import org.springframework.context.annotation.ImportSelector;
     4 import org.springframework.core.type.AnnotationMetadata;
     5 
     6 public class JamesImportSelector implements ImportSelector {
     7 
     8     @Override
     9     public String[] selectImports(AnnotationMetadata annotationMetadata) {
    10         // 返回全类名的bean
    11         return new String[]{"com.enjoy.cap6.bean.Fish", "com.enjoy.cap6.bean.Tiger"};
    12     }
    13 }
     1 import com.enjoy.cap6.config.Cap6MainConfig;
     2 import org.junit.Test;
     3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
     4 
     5 public class Cap6Test {
     6 
     7     @Test
     8     public void test01(){
     9         // 创建容器将bean加载进来
    10         AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap6MainConfig.class);
    11 
    12         System.out.println("IOC容器创建完成........");
    13         String[] beanDefinitionNames = app.getBeanDefinitionNames();
    14 
    15         for(String name: beanDefinitionNames){
    16             System.out.println(name);
    17         }
    18 
    19     }
    20 }
    给容器中添加person....
    IOC容器创建完成........
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.event.internalEventListenerProcessor
    org.springframework.context.event.internalEventListenerFactory
    cap6MainConfig
    com.enjoy.cap6.bean.Dog
    com.enjoy.cap6.bean.Cat
    com.enjoy.cap6.bean.Fish
    com.enjoy.cap6.bean.Tiger
    person

    /**
    * 给我们容器中注册组件:
    * 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用
    * 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个
    * 3.@import:[快速给容器导入一个组件] 注意:@Bean有点简单
    * a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id)
    * b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
    * c. ImportBeanDefinitionRegistrar:可以手动天剑组件到IOC容器,所有Bean的注册可以使用BeanDefinitionRegistry
    * 4.使用Spring提供的FactoryBean(工厂bean)进行注册:把bean注入到容器中
    */
     1 package com.enjoy.cap6.config;
     2 
     3 
     4 import com.enjoy.cap1.Person;
     5 import com.enjoy.cap6.bean.Cat;
     6 import com.enjoy.cap6.bean.Dog;
     7 import org.springframework.context.annotation.Bean;
     8 import org.springframework.context.annotation.Configuration;
     9 import org.springframework.context.annotation.Import;
    10 
    11 
    12 @Configuration
    13 @Import(value={Dog.class, Cat.class, JamesImportSelector.class})  // 相当与new一个对象放到容器中
    14 
    15 public class Cap6MainConfig {
    16 
    17    /**
    18     * 给我们容器中注册组件:
    19     * 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用
    20     * 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个
    21     * 3.@import:[快速给容器导入一个组件]  注意:@Bean有点简单
    22     *      a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id)
    23     *      b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
    24     *      c. ImportBeanDefinitionRegistrar:可以手动天剑组件到IOC容器,所有Bean的注册可以使用BeanDefinitionRegistry
    25     */
    26     // 容器启动时初始化person的bean实例
    27     @Bean("person")
    28     public Person person(){
    29         System.out.println("给容器中添加person....");
    30         return new Person("person", 20);
    31     }
    32 
    33 }
     1 package com.enjoy.cap6.config;
     2 
     3 import com.enjoy.cap6.bean.Pig;
     4 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
     5 import org.springframework.beans.factory.support.RootBeanDefinition;
     6 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
     7 import org.springframework.core.type.AnnotationMetadata;
     8 
     9 public class JamesImportBeanfinitionRegistrar implements ImportBeanDefinitionRegistrar {
    10 
    11     /**
    12      * AnnotationMetadata:当前类的注解信息
    13      * BeanDefinitionRegistry:BeanDefinition注册类
    14      *    把所有需要添加到容器中的bean加入;
    15      *
    16      **/
    17     @Override
    18     public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
    19 
    20         // 面试官:当容器中存在cat dog 才往容器中添加pig
    21 
    22         // 判断bean是否存在
    23         boolean beanDog = beanDefinitionRegistry.containsBeanDefinition("com.enjoy.cap6.bean.Dog");
    24         boolean beanCat = beanDefinitionRegistry.containsBeanDefinition("com.enjoy.cap6.bean.Cat");
    25 
    26         //对于我们要注册的bean,给bean进行封装     RootBeanDefinition
    27 
    28         // 如果dog和cat同时存在ioc容器中,那么创建pig类加入到容器当中。
    29         if(beanCat && beanDog){
    30             RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class);  // 特有的容器封装
    31             beanDefinitionRegistry.registerBeanDefinition("Pig", beanDefinition);
    32         }
    33     }
    34 }

    Error:(30, 49) java: 无法访问java.util.function.Supplier
    找不到java.util.function.Supplier的类文件

    java编译环境出错 打开File--->Projrct Struct 设置JDK版本解决

    Factorybean接口实现

    1,getObject()返回对象方法;

    2,getObjectType返回对象类型

    3, isSingleton()是否单例控制

     1 package com.enjoy.cap6.config;
     2 
     3 import com.enjoy.cap6.bean.Monkey;
     4 import org.springframework.beans.factory.FactoryBean;
     5 
     6 public class JamesFactoryBean implements FactoryBean<Monkey> {
     7     @Override
     8     public Monkey getObject() throws Exception {
     9         return new Monkey();
    10     }
    11 
    12     @Override
    13     public Class<?> getObjectType() {
    14         return Monkey.class;
    15     }
    16 
    17     // 是否单例模式  true 单实例    false 多实例
    18     @Override
    19     public boolean isSingleton() {
    20         return false;
    21     }
    22 }
     1 package com.enjoy.cap6.config;
     2 
     3 import com.enjoy.cap1.Person;
     4 import com.enjoy.cap6.bean.Cat;
     5 import com.enjoy.cap6.bean.Dog;
     6 import org.springframework.context.annotation.Bean;
     7 import org.springframework.context.annotation.Configuration;
     8 import org.springframework.context.annotation.Import;
     9 
    10 @Configuration
    11 @Import(value={Dog.class, Cat.class, JamesImportSelector.class, JamesImportBeanDefinitionRegistrar.class})  // 相当与new一个对象放到容器中
    12 
    13 public class Cap6MainConfig {
    14 
    15    /**
    16     * 给我们容器中注册组件:
    17     * 1.@Bean:[导入第三方的类或包的组件],比如person为第三方的类,需要再IOC容器中使用
    18     * 2.包扫描+组件的标注注解(@ComponentScan:@controller @Service @Component),一般是针对自己写的类。使用这个
    19     * 3.@import:[快速给容器导入一个组件]  注意:@Bean有点简单
    20     *      a. @Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名(路径+id)
    21     *      b. ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
    22     *      c. ImportBeanDefinitionRegistrar:可以手动天剑组件到IOC容器,所有Bean的注册可以使用BeanDefinitionRegistry
    23     * 4.使用Spring提供的FactoryBean(工厂bean)进行注册:把bean注入到容器中
    24     */
    25     // 容器启动时初始化person的bean实例
    26     @Bean("person")
    27     public Person person(){
    28         System.out.println("给容器中添加person....");
    29         return new Person("person", 20);
    30     }
    31 
    32     @Bean
    33     public JamesFactoryBean jamesFactoryBean(){
    34         return new JamesFactoryBean();
    35     }
    36 
    37 }
     1 import com.enjoy.cap6.config.Cap6MainConfig;
     2 import org.junit.Test;
     3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
     4 
     5 public class Cap6Test {
     6 
     7     @Test
     8     public void test01(){
     9         // 创建容器将bean加载进来
    10         AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap6MainConfig.class);
    11 
    12         System.out.println("IOC容器创建完成........");
    13         String[] beanDefinitionNames = app.getBeanDefinitionNames();
    14 
    15         for(String name: beanDefinitionNames){
    16             System.out.println(name);
    17         }
    18 
    19         Object bean1 = app.getBean("jamesFactoryBean");
    20         System.out.println("bean的类型="+bean1.getClass());
    21     }
    22 }

    生命周期-初始化与销毁

    如何定义和销毁3种方式;

    • 1, 指定初始化和销毁方法
    • 2,让Bean实现 InitializingBean(定义初始化逻辑)
    • 3, 使用JSR250规则定义的两个注解来实现
  • 相关阅读:
    Hutool工具类TreeUtil的使用(记录)
    mybatisplus开启sql日志打印
    Java8流式编程GroupBy和求最值示例
    使用Iterator对List集合进行增加或者删除操作时报异常的分析
    基于Redis实现分布式定时任务调度
    mybatisplus分页查询
    curl转json,swagger文档转json存储自动化测试平台
    mysql 概述
    聚集索引和非聚集索引
    如何编写高性能sql
  • 原文地址:https://www.cnblogs.com/JCcodeblgos/p/11516591.html
Copyright © 2020-2023  润新知