Fork me on GitHub

Spring注解:@Lazy,@Conditional,@import,FactoryBean接口

1.@Lazy懒加载

懒加载:针对单实例的

单实例bean,默认在容器启动的时候创建对象

懒加载就是:容器启动的时候不创建对象,在第一次获取bean的时候创建对象,并且初始化、

Config2.class

1
2
3
4
5
6
7
8
@Configuration
public class Config2 {
@Bean("per")
public Person person(){
System.out.println("person对象创建完成");
return new Person("MrChengs",20);
}
}

测试

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

此时并没有去获取Person对象!

此时容器创建之后就会实例化对象

1
2
person对象创建完成
容器创建完成...

使用懒加载:

1
2
3
4
5
6
7
8
9
@Configuration
public class Config2 {
@Lazy
@Bean("per")
public Person person(){
System.out.println("person对象创建完成");
return new Person("MrChengs",20);
}
}

测试:

容器创建完成…

2..@Conditional

按照一定的条件判断,满足条件给容器注册

可以在类上也可以在方法上

放置在类上,满足 条件,配置的所有的bean都会生效

假设在windows和Linux操作系统获取自动的注册信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}
}
1
2
3
4
5
6
7
8
9
@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
容器创建完成…

3.@import

快速的给容器中导入一个组建

默认创建的是bean是组建的全类名

1
2
3
4
5
@Configuration
@Import(Person.class)
public class Config2 {

}
1
2
3
4
5
6
7
8
9
@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
容器创建完成…

源码:

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

可以同时传入多个

1
@Import({Person.class,xxxxx})

直接注入到容器中

ImportSelector

是一个接口

1
2
3
4
5
6
7
8
9
public class MyImportSelector implements ImportSelector{
//返回值就是需要导入到容器中的全类名
//AnnotationMetadata : 就是获取标注@Import()注解类的所有信息
public String[] selectImports(AnnotationMetadata importingClassMetadata) {


return new String[]{"coom.MrChengs.bean.Person"};
}
}
1
2
3
4
@Configuration
@Import({MyImportSelector.class})
public class Config2 {
}
1
2
3
4
5
6
7
8
9
@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接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 );
}
}
}
1
2
3
4
@Configuration
@Import({MyImportBeanDefinitionRegistrar.class})
public class Config2 {
}
1
2
3
4
5
6
7
8
9
@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接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}
}
1
2
3
4
5
6
7
8
@Configuration
public class Config2 {

@Bean
public PersonFactoryBean personFactoryBean(){
return new PersonFactoryBean();
}
}
1
2
3
4
5
6
7
8
9
10
11
@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("容器创建完成...");
}
1
2
3
4
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

原文链接

相关文章

微信打赏

赞赏是不耍流氓的鼓励

评论系统未开启,无法评论!