spring基于注解
一、组件注册
给容器中注册组件:
- 包扫描+组件标记注解( @Controller, @Service,@Repository,@Component )。
- @Bean [快速导入第三方包里面的组件]。
- @Import [快速给容器中导入一个组件]。 直接标注在java配置文件的类上,快速引入第三方组件. @Import({ 要导入的组件类名.class }),bean的id默认为全类名。
- @ImportSelector 批量快速导入第三方组件。
- @@ImportBeanDefinitionRegister 手动批量导入第三方组件。
- FactoryBean注册Bean。
1、java配置类注解@configuration和@bean
- 基于注解的Spring容器的实例类为: AnnotationConfigApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class, JavaConfig2.class);
- @configuration :
- 被标记的文件为java配置文件。相当于xml配置文件。
- spring允许多个@configuration标记的java配置文件同时存在且读取。
- @bean:
- 用于@configuration的java配置文件中的方法, 被@Bean标记的方法,被称为工厂方法。
- Bean创建时,如果不指定value属性,那么默认为工厂方法的名字作为bean的id属性值。
## java配置类1
@Configuration
public class JavaConfig {
@Bean
public HelloWorld helloWorld2(){
return new HelloWorld();
}
}
## java配置类2
@Configuration
public class JavaConfig2 {
@Bean
public HelloWorld helloWorld1(){
return new HelloWorld();
}
}
## 创建IOC容器,并获取bean
## 创建IOC容器,并且读取配置文件
ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class, JavaConfig2.class);
HelloWorld helloWorld1 = (HelloWorld) context.getBean("helloWorld1");
System.out.println(helloWorld1);
HelloWorld helloWorld2 = (HelloWorld) context.getBean("helloWorld2");
System.out.println(helloWorld2);
2、@ComponentScan自动扫描注解,@CompentScan.Filter使用
- @ComponentScan : value,指明要扫描的包;
- excludeFilters = Filter[],指定扫描的时候按照什么规则排除组件。
- includeFilters = Filter[],指定扫描的时候只需要包含哪些组件。
- @CompoentScan设置一个或者多个扫描路径。
(1)@ComponentScan 表示设置需要扫描的文件夹以及子文件夹。
(2) jdk1.8以后,允许设置多个@ComponentScan来设置需要扫描的多个文件夹路径。 如果不支持配置多个,可以用一下方式。@ComponentScans({ @ComponentScan("com.mz.controller"), @ComponentScan("com.mz.service") })
2.1、@ComponentScan使用
# java配置文件
# @Configuration 表示被修饰的类是java配置类。
# @ComponentScan 表示设置需要扫描的文件夹以及子文件夹。
# jdk1.8以后,允许设置多个@ComponentScan来设置需要扫描的多个文件夹路径。
@Configuration
@ComponentScan( value="com.mz" )
public class JavaConfig {
}
# @Controller
@Controller
public HelloController {
public void test(){
System.out.println("hello controller");
}
}
# @Service
@Service
public HelloService {
public void test(){
System.out.println("hello service");
}
}
2.2、@CompentScan,excludeFilter, @Component.Filter的使用
- excludeFilter表示扫描路径下,需要排除的类型。
# java配置类
@Configuration
@ComponentScan( value="com.mz", excludeFilter = {
@ComponentScan.Filter( type=FilterType.ANNOTATION, classes = {
Controller.class } )
} )
2.3、@CompentScan, includeFilter, @Component.Filter的使用
- includeFilter表示扫描路径下,需要包含的类型;如果不是该类型,则排除。
- includeFilter的使用,必须要设置useDefaultFilters=false才能生效。
@Configuration
@ComponentScan( value="com.mz", includeFilter = {
@ComponentScan.Filter( type = FilterType.ANNOTATION, classes = {
Controller.class , Service.class })
}, useDefaultFilters = false )
3、@ComponentScan.Filter过滤规则 与自定义过滤规则
- FilterType的类型
- FilterType. ANNOTATION : 按照标注的注解类型进行过滤。
- FilterType.ASSIGNABLE_TYPE : 按照标注的注解的类的实际类型进行过滤。
- FilterType.ASPECTJ : AspectJ表达式。(基本不使用)
- FilterType.REGEX : 按照正则表达式进行过滤。
- FilterType.CUSTOM : 自定义过滤规则。
3.1、TypeFilter接口实现:
- springIOC会扫描指定路径的所有文件,然后调用 MyTypeFilter的match方法,来判断当前扫描到的类是否需要创建实例。
- match方法的两个参数:metadataReader : 读取到的当前正在扫描的类的信息。metadataReaderFactory : 可以所有已经扫描到的类的信息。
- 可以通过metadataReader获取当前类的注解信息,获取当前类的类信息,获取当前类资源(指出当前文件所在的路径)。
# 关于type=FilterType.CUSTOM的使用
# java配置类
@Configuration
@ComponentScan( value="com.mz", includeFilters = {
@Component.Filter( type=FilterType.CUSTOM, classes = {
MyTypeFilter.class } )
} )
public class JavaConfig {
}
# TypeFilter接口的实现
public class MyTypeFilter implements TypeFilter {
/**
* springIOC会扫描指定路径的所有文件,然后调用 MyTypeFilter的match方法,来判断当前扫描到的类是否需要创建实例。
* 如果是返回true,则创建;如果是返回false,则不创建。
*
* metadataReader : 读取到的当前正在扫描的类的信息。
* metadataReaderFactory : 可以所有已经扫描到的类的信息。
* */
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类的注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源(指出当前文件所在的路径)
Resource resource = metadataReader.