码迷,mamicode.com
首页 > 编程语言 > 详细

Spring应用于组件注册的注解(一)

时间:2019-10-08 00:59:04      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:value   color   public   判断   属性   构建   object   引入   ica   

在将Spring框架应用于项目开发中时,繁多的xml配置文件会使项目的维护升级变得困难,特别是项目很大时,有时候会花掉大量的时间去定位相应的组件配置。为了解决这个问题,引入Spring框架中的强大注解变得很重要,同时,注解的学习更是为后期学习Spring Boot做好了铺垫。

@Configuration

@Configuration注解用于定义配置类,并用于构建bean定义,初始化Spring容器,被标注的类类似于Spring的xml配置文件中的标签。

@Bean

给容器注册一个Bean;类型为方法返回值类型,id不指定时默认使用方法名作为id。

@ComponentScan

配置自动扫描相应的包。会自动扫描包路径下面的所有@Controller、@Service、@Repository、@Component 的类。包含的属性如下:

  • value:指定扫描的包路径。接收String数组。
  • @Filter:声明扫描包的过滤规则,可以按注解、类型、正则表达式等进行过滤。

@ComponentScans

如果是JDK8以上可以声明多个@ComponentScan进行配置,也可以在@ComponentScans中配置多个@ComponentScan。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@Configuration //告诉spring这是一个配置文件
@ComponentScan(value="com.jt",/*excludeFilters*/ includeFilters = {
@Filter(type=FilterType.ANNOTATION,classes={Controller.class,Service.class})},useDefaultFilters=false)//配置自动扫描相应的包
/*@ComponentScans(value = {
@ComponentScan(value="com.jt",excludeFilters = {
@Filter(type=FilterType.ANNOTATION,classes={Controller.class,Service.class})})
})*/
/**@ComponentScan vaue:指定要扫描的包
*excludeFilters = Filter[],指定扫描的时候按照什么规则排除哪些组件。
*includeFilters = Filter[],指定扫描的时候只包含哪些组件。生效的前提是让useDefaultFilters
*FilterType.ANNOTATION 按照注解
*FilterType.ASSIGNABLE_TYPE 按照给定的类型
*FilterType.ASPECTJ 使用ASPECTJ表达式
*FilterType.REGEX 使用正则表达式
*FilterType.CUSTOM 使用自定义规则(需要实现TypeFilter接口)
*
*/
public class MainConfig {

//给容器注册一个Bean;类型为返回值类型,id不指定时默认使用方法名作为id
@Bean("person1")
public Person person(){
return new Person("lishi",20);
}

}

@Scope

控制Bean的作用范围。

@Lazy

懒加载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /**默认是单实例的
* prototype:多实例:ioc容器启动时并不会去调用方法创建对象,
* 而是每次获取的时候才调用方法去创建对象。
* singleton:单实例(默认值):ioc容器启动时会调用方法创建对象并放入容器中。
* 以后每次获取是直接从容器(map.get())中获取。
* request:同一次请求创建一个实例
* session:同一个session创建一个实例
*
*
* 懒加载:对于单实例的Bean,默认容器启动的时候创建对象;
* 懒加载就是容器启动的时候不创建对象,而是第一次获取(map.get())对象时才初始化对象。
* */
@Scope("prototype")
@Lazy
@Bean("person")
public Person person(){
System.out.println("获取Person....");
return new Person("张三",25);
}

@Conditional(条件注解)

标注在方法上时,按照一定的条件进行动态转配,满足条件才给容器中注册Bean。标注在配置类上时,满足当前条件,这个类配置中的所有Bean才能生效。其中这个条件类必须实现Condition接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   /**
* @Conditional({Condition}):按照一定的条件进行动态转配,满足条件才给容器中注册Bean
*
* 如果系统是Windows,给容器中注册bill
* 如果系统是Linux,给容器中注册Linus
*
* */
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01(){
return new Person("Bill Gates",60);
}

@Conditional({LinuxCondition.class})
@Bean("linus")
public Person person02(){
return new Person("linus",40);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//判断对象是否是linux
public class implements Condition{

/**
* ConditionContext:判断条件能使用的上下文(环境)
* AnnotatedTypeMetadata:标注了@Conditional的注释信息
* */
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 difinition = registry.containsBeanDefinition("person");
String property = environment.getProperty("os.name");
if(property.contains("linux")){
return true;
}
return false;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//判断系统是否是windows
public class WindowsCondition implements Condition{

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 判断是否Windows
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows")){
return true;
}
return false;
}

}
@Import

快速给容器中注册组件。id默认是全类名。

1
2
3
4
({Color.class})//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {
//...
}
  • ImportSelector:如果某个类实现了ImportSelector接口,通过重写接口中的方法selectImports,可以将需要注册的类的全类名返回给@Import注解,并实现批量注册。
1
2
3
4
({MyImportSelector.class})//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {
//.....
}
1
2
3
4
5
6
7
8
9
10
11
12
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector{

//返回值就是要注册到容器中的组件
//AnnotationMetadata:当前标注@Import注解的类的所有注解信息
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// TODO Auto-generated method stub
//可以返回空数组,但是不能是null,否则会包空指针异常。
return new String[]{"com.jt.bean.Color","com.jt.bean.Red"};
}

}
  • ImportBeanDefinitionRegistrar:手动注册Bean到容器中。
1
2
3
4
({MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {
//...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

/**
* AnnotationMetadata:当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类;
* 把所有需要添加到容器中的Bean,调用
* BeanDefinitionRegistry.registerBeanDefinition手工注册进容器
* */
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//定义注册Bean的条件
boolean difinition = registry.containsBeanDefinition("com.jt.bean.Red");
if(difinition){
//指定Bean的定义信息(Bean的类型,Bean的作用域...)
RootBeanDefinition paramBeanDefinition = new RootBeanDefinition(RainBow.class);
//注册一个bean,指定bean的别名
registry.registerBeanDefinition("com.jt.bean.RainBow", paramBeanDefinition);
}
}

}

使用FactoryBean注册组件

Spring提供了一个org.Springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。

1
2
3
4
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color>{

//返回一个Color对象,这个对象会注册到容器中
public Color getObject() throws Exception {
// TODO Auto-generated method stub
System.out.println("ColorFactoryBean...getObject()...");
return new Color();
}

public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Color.class;
}

//是否单实例
//true:这个bean是单实例,在容器中保存一份
//false:多实例,每次获取都会创建一个新的bean
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testImport(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
printBeans(applicationContext);
//工厂Bean获取到的是调用getObject()创建的对象
Object object = applicationContext.getBean("colorFactoryBean");
Object object2 = applicationContext.getBean("colorFactoryBean");
System.out.println(object);
System.out.println(object == object2);

//获取colorFactoryBean本身
Object object3 = applicationContext.getBean("&colorFactoryBean");
System.out.println(object3);
}

原文:大专栏  Spring应用于组件注册的注解(一)


Spring应用于组件注册的注解(一)

标签:value   color   public   判断   属性   构建   object   引入   ica   

原文地址:https://www.cnblogs.com/peterchan1/p/11633167.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!