1. 程式人生 > >2spring註解:@Lazy,@Conditional,@import,FactoryBean介面

2spring註解:@Lazy,@Conditional,@import,FactoryBean介面

大致的工程內容也來源於上一篇博文! 

https://www.cnblogs.com/Mrchengs/p/10108603.html 

 

 [email protected]懶載入

 懶載入:針對單例項的

 單例項bean,預設在容器啟動的時候建立物件

 懶載入就是:容器啟動的時候不建立物件,在第一次獲取bean的時候建立物件,並且初始化、

 

 Config2.class

@Configuration
public class Config2 {
     @Bean("per")
     
public Person person(){ System.out.println("person物件建立完成"); return new Person("MrChengs",20); } }

 測試

     @Test
     public void test2(){
           ApplicationContext app = new  AnnotationConfigApplicationContext(Config2.class);
           String [] names = app.getBeanDefinitionNames();
           System.
out.println("容器建立完成..."); }

此時並沒有去獲取Person物件!

此時容器建立之後就會例項化物件

person物件建立完成
容器建立完成...

 

 使用懶載入:

@Configuration
public class Config2 {
     @Lazy
     @Bean("per")
     public Person person(){
           System.out.println("person物件建立完成");
           return new Person("MrChengs
",20); } }

 測試:

容器建立完成...

 

 [email protected]

按照一定的條件判斷, 滿足條件給容器註冊 可以在類上也可以在方法上 放置在類上,滿足 條件,配置的所有的bean都會生效

 

 假設在windows和Linux作業系統獲取自動的註冊資訊

@Configuration
public class Config2 {
     @Lazy
     @Bean("per")
     public Person person(){
           System.out.println("person物件建立完成");
           return new Person("MrChengs",20);
     }
     
     //按照一定的條件判斷,滿足條件給容器註冊
     
     @Conditional({LinuxCondition.class})
     @Bean("person1")
     public Person person1(){
           return new Person("Mr",12);
     }
     
     @Conditional({WindowsCondition.class})
     @Bean("person2")
     public Person person2(){
           return new Person("Mx",20);
     }
}
public class LinuxCondition implements Condition{
     //ConditionContext:判條件能使用的上下文
     //AnnotatedTypeMetadata:註釋資訊
     public boolean matches(ConditionContext context,  AnnotatedTypeMetadata metadata) {
           
           //能獲取到IOC容器使用的beanfactory
           ConfigurableListableBeanFactory c =  context.getBeanFactory();
           //獲取載入器
           ClassLoader classLoader = context.getClassLoader();
           //獲取當前的環境資訊
           //Environment environment =   (Environment)  context.getEnvironment();
           //獲取bean定義註冊的類
           BeanDefinitionRegistry resistroy =  context.getRegistry();
           
       //獲取當前的作業系統 String name
= context.getEnvironment().getProperty("os.name"); if(name.contains("Linux")){ return true; } return false; } }
public class WindowsCondition implements Condition{
     //ConditionContext:判條件能使用的上下文
     //AnnotatedTypeMetadata:註釋資訊
     public boolean matches(ConditionContext context,  AnnotatedTypeMetadata metadata) {
           
           //能獲取到IOC容器使用的beanfactory
           ConfigurableListableBeanFactory c =  context.getBeanFactory();
           //獲取載入器
           ClassLoader classLoader = context.getClassLoader();
           //獲取當前的環境資訊
           //Environment environment =   (Environment)  context.getEnvironment();
           //獲取bean定義註冊的類
           BeanDefinitionRegistry resistroy =  context.getRegistry();
           
           String name =  context.getEnvironment().getProperty("os.name");
           if(name.contains("Win")){
                return true;
           }
           return false;
     }
}
     @Test
     public void test3(){
           ApplicationContext app = new  AnnotationConfigApplicationContext(Config2.class);
           String [] names =  app.getBeanNamesForType(Person.class);
           for(String name : names){
                System.out.println(name);
           }
           System.out.println("容器建立完成...");
     }
per
person2
容器建立完成...

 

[email protected]

快速的給容器中匯入一個組建 預設 建立的是bean是組建的全類名
@Configuration
@Import(Person.class)
public class Config2 {

}
     @Test
     public void test3(){
           ApplicationContext app = new  AnnotationConfigApplicationContext(Config2.class);
           String [] names =  app.getBeanNamesForType(Person.class);
           for(String name : names){
                System.out.println(name);
           }
           System.out.println("容器建立完成...");
     }
coom.MrChengs.bean.Person
容器建立完成...

 

原始碼:

public @interface Import {
     /**
      * {@link Configuration}, {@link ImportSelector}, {@link  ImportBeanDefinitionRegistrar}
      * or regular component classes to import.
      */
     Class<?>[] value();
}

 

可以同時傳入多個

@Import({Person.class,xxxxx})

直接注入到容器中

 

ImportSelector

是一個介面

public class MyImportSelector implements ImportSelector{
     //返回值就是需要匯入到容器中的全類名
     //AnnotationMetadata : 就是獲取標註@Import()註解類的所有資訊
     public String[] selectImports(AnnotationMetadata  importingClassMetadata) {
           
           
           return new String[]{"coom.MrChengs.bean.Person"};
     }
}
@Configuration
@Import({MyImportSelector.class})
public class Config2 {
}
@Test
     public void test3(){
           ApplicationContext app = new  AnnotationConfigApplicationContext(Config2.class);
           String [] names = app.getBeanDefinitionNames();
           for(String name : names){
                System.out.println(name);
           }
           System.out.println("容器建立完成...");
     }
config2
coom.MrChengs.bean.Person
容器建立完成...

 

ImportBeanDefinitionRegistrar介面

public class MyImportBeanDefinitionRegistrar implements  ImportBeanDefinitionRegistrar {
     //AnnotationMetadata:當前類的註解資訊
     //BeanDefinitionRegistry:註冊類
     public void registerBeanDefinitions(AnnotationMetadata  importingClassMetadata, BeanDefinitionRegistry registry) {
           
           //coom.MrChengs.bean.Person
           //判斷當前類是否有下面的這個bean
           boolean a =  registry.containsBeanDefinition("coom.MrChengs.bean.Person");
           //如果沒有我們進行註冊
           if(!a){
                RootBeanDefinition beanDefinition = new  RootBeanDefinition(Person.class);
                //指定bean的名字
                //註冊一個bean
                registry.registerBeanDefinition("peson",  beanDefinition );
           }
     }
}
@Configuration
@Import({MyImportBeanDefinitionRegistrar.class})
public class Config2 {
}
@Test
     public void test3(){
           ApplicationContext app = new  AnnotationConfigApplicationContext(Config2.class);
           String [] names = app.getBeanDefinitionNames();
           for(String name : names){
                System.out.println(name);
           }
           System.out.println("容器建立完成...");
     }
config2
peson
容器建立完成...

 

4.FactoryBean介面

public class PersonFactoryBean implements FactoryBean<Person>{

     //返回一個person物件,這個物件會新增到容器中
     public Person getObject() throws Exception {
           // TODO Auto-generated method stub
           return new Person();
     }

     //返回型別
     public Class<?> getObjectType() {
           // TODO Auto-generated method stub
           return Person.class;
     }

     //是單例嗎?
     public boolean isSingleton() {
           // TODO Auto-generated method stub
           return false;
     }
}
@Configuration
public class Config2 {
     
     @Bean
     public PersonFactoryBean personFactoryBean(){
           return new PersonFactoryBean();
     }
}
     @Test
     public void test3(){
           ApplicationContext app = new  AnnotationConfigApplicationContext(Config2.class);
           String [] names = app.getBeanDefinitionNames();
           for(String name : names){
                System.out.println(name);
           }
           Object name =  app.getBean("personFactoryBean").getClass();
           System.out.println(name);
           System.out.println("容器建立完成...");
     }
config2
personFactoryBean
class coom.MrChengs.bean.Person   -> Object name =  app.getBean("personFactoryBean").getClass();
容器建立完成...

得到的是Person物件

 

預設得到的是getObject的物件   給id前面加一個& 符號得到的是物件本身 Object name = app.getBean("&personFactoryBean").getClass(); class coom.MrChengs.bean.PersonFactoryBean