在如今Spring Boot、Spring Cloud的兴起,Spring注解开发已成为主流开发模式。本篇将介绍常用的组件注册方式。
环境准备
新建Maven项目,添加依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.26.RELEASE</version>
</dependency>
</dependencies>
1、@Configuration @Bean
新增Person类
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
新增config类
@Configuration
public class ApplicationConfig {
/*
默认name是获取Bean的方法名 person
@Bean("person001") 这样使用注解 name则为person001
*/
@Bean
public Person person(){
return new Person("小符",18);
}
}
获取Bean
public class Application {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
Object person = context.getBean("person");
System.out.println(person);
}
}
输出
2、@ComponentScan
自动扫描包方式
扫描如下注解:
- @Controller
- @Service
- @Repository
- @Component
在bean下新建一个类并加上@Component注解表示将该Bean注册到容器中
@Component
public class Animal {
}
在Config类中加入注解
@Configuration
@ComponentScan("com.fred.bean")
public class ApplicationConfig {
/*
默认name是获取Bean的方法名 person
@Bean("person001") 这样使用注解 name则为person001
*/
@Bean
public Person person(){
return new Person("小符",18);
}
}
@ComponentScan注解加上 value:com.fred.bean表示扫描这个包下的Bean(前提是Bean上有注解@Controller、@Service、@Repository、@Component 中的其中一个)才能被扫描到。
输出当前容器容器中的存在的Bean的name
public class Application {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
// Object person = context.getBean("person");
// System.out.println(person);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
输出
可以看到,除了Spring自己注册的Bean,以及之前注入的Bean,刚刚加入的Animal也存在容器中了。
@ComponentScan也可以不写参数,则默认扫描的是当前注解的类的包下。
例如@ComponentScan注解的是ApplicationConfig类com.fred.config.ApplicationConfig
则等同于@ComponentScan("com.fred.config")的效果
2.1 、使用FilterType指定扫描过滤规则
有以下几种方式实现过滤
public enum FilterType {
ANNOTATION,//注解
ASSIGNABLE_TYPE,//类型
ASPECTJ,//ASPECT表达式
REGEX,//正则表达式
CUSTOM;//自定义
private FilterType() {
}
}
默认是 ANNOTATION
excludeFilters
excludeFilters的作用是排除过滤
@Configuration
@ComponentScan(value = "com.fred.bean",excludeFilters = {
@ComponentScan.Filter(Service.class)
})
public class ApplicationConfig {
/*
默认name是获取Bean的方法名 person
@Bean("person001") 这样使用注解 name则为person001
*/
@Bean
public Person person(){
return new Person("小符",18);
}
}
排除Service注解的Bean
修改Inner类注解为@Service
@Service
public class Inner {
}
输出当前容器容器中的存在的Bean的name
可以看到Inner就被排除了。
使用ASSIGNABLE_TYPE方式
@Configuration
@ComponentScan(value = "com.fred.bean",excludeFilters = {
//Filter默认是 FilterType.ANNOTATION
//@ComponentScan.Filter(Service.class)
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Inner.class})
})
public class ApplicationConfig {
/*
默认name是获取Bean的方法名 person
@Bean("person001") 这样使用注解 name则为person001
*/
@Bean
public Person person(){
return new Person("小符",18);
}
}
输出当前容器容器中的存在的Bean的name
InnerBean就被排除了。
使用CUSTOM方式
自定义需要实现TypeFilter接口
public class MyFilterType implements TypeFilter {
/*
参数:
annotationMetadata 可以获取到扫描到Bean的注解相关信息 Class相关信息 资源信息等
metadataReaderFactory 可以获取父类、接口等
返回值True表示要排除 false则不排除
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
System.out.println(metadataReader.getClassMetadata().getClassName());
//如果是Animal就排除
if (metadataReader.getClassMetadata().getClassName().equals("com.fred.bean.Animal")) {
return true;
}
//其他都不排除
return false;
}
}
输出当前容器容器中的存在的Bean的name
可以看到Animal被排除了。
includeFilters
includeFilters和excludeFilters用法大同小异,作用是包含。
需要注意的是@ComponentScan的useDefaultFilters默认为Ture表示会自动扫描 @Component、@Repository、 @Service、@Controller,为True的情况下设置includeFilters只包含@Controller注解的Bean,@Component、@Repository、 @Service也会被自动扫描到。根据需求需要可设置为False。
项目结构