@Configuration
该注解标注的类为javaconfig类,并且会把该类放入到ioc的容器中
也就是标注了我们这个注解的类,相当于我们以前的配置文件
@Bean
想ioc的容器中引入组件,一般写在配置类中,默认是单实例的
组件的id是方法名,组件的类型就是返回值类型
@Lazy:设置为懒加载,和@Bean一块使用,使用到对象的时候,才会加载这个类
@Scope(“prototype”):设置类的作用域,默认不写是单实例的
Scope参数取值:
singleton://单实例;
prototype://多实例;
request://一个请求创建一个实例;
session://一个会话创建一个实例;
@Configuration和@Bean测试:
/**
* proxyBeanMethods参数:
* 是否代理bean的方法
* Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
* Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
* 组件依赖必须使用Full模式默认。其他默认是否Lite模式
*/
@Configuration(proxyBeanMethods = true) //--标注这个类就是一个配置类,相当于我们以前编写的xml文件
public class MyConfig {
@Bean //向ioc工厂注入一个bean,默认单实例,id为方法名:person/ 类型为返回值类型:Person
public Person person(){
return new Person("张三",18);
}
@Bean //作用同上
public Pet pet(){
return new Pet("大黄",3);
}
}
结果:
@Component、@Controller、@Service、@Repository
作用同我们以前的方式
@ComponentScan
和我们以前在xml中配置扫描路径是一样的,只要扫描的路径中有spring的注入注解,那么就可以注入进去。
这个注解还有一些其他的属性:排除那些类不扫描和加载那些类,只要满足条件就会加载进去
测试:
@Configuration
@ComponentScan(
includeFilters ={
@ComponentScan.Filter(type= FilterType.ANNOTATION,classes = {
Controller.class})
},
useDefaultFilters = false
//excludeFilters用法同上,不演示
)
public class MyConfig01 {
}
- includeFilters :让那些加载进ioc容器,如果要使用这个,则必须在下面添加useDefaultFilters = false,才能生效
- excludeFilters:不让那些加载进ioc容器
- type的取值:
type 取值的泛型类 FilterType 有以下几种取值:
ANNOTATION:使用注解过滤;
ASSIGNABLE_TYPE:使用给定的类型;
ASPECTJ:使用 ASPECTJ 表达式;
REGEX:使用正则表达式;
CUSTOM:使用自定义规则,需要提供一个 TypeFilter 的实现类;
自定义过滤器:
//要实现TypeFilter接口,重写match方法
public class MyFilter implements TypeFilter {
/**
* metadataReader:读取当前正在扫描的类的信元数据;
* metadataReaderFactory:可以获取其他任何类的元数据。
* @return 是否加载进ioc的容器中
* @throws IOException
*/
@Override
public boolean match(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
//===================metadataReader的常用方法==============================
// 获取当前类的注解元数据
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 获取当前正在扫描的类的元数据
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
//=====================================================
//测试:只要包含er的类,就不加在进ioc容器
// 获取当前正在扫描的类的元数据
ClassMetadata classMetadata1 = metadataReader.getClassMetadata();
//获取名称
String className = classMetadata1.getClassName();
//判断并返回
return className.contains("er");
}
}
@Conditional():判断组件是否满足条件,满足创建,不满足不创建
public @interface Conditional {
Class<? extends Condition>[] value();
}
这个注解的参数里面可以放很多的我们自定义的判断器,只需要写一个类集成Condition类,实现方法即可。
public class aaa implements Condition {
/**
*
* @param conditionContext 当前应用的上下文环境。
* @param annotatedTypeMetadata 标注了该注解的类的信息
* @return true:符合条件。false:不符合条件
*/
@Override
public boolean matches(ConditionContext conditionContext,
AnnotatedTypeMetadata annotatedTypeMetadata) {
return false;
}
}
//======================================
@Conditional({
xxx.class})
public class MyConfig01 {
}
这个注解还衍生除了很多子注解:
@ConditionalOnBean:当容器中有指定的Bean的条件下
@ConditionalOnClass:当类路径下有指定的类的条件下
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean:当容器中没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径下是否有指定的资源
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean
我们可以根据这些注解来判断那些类可以注入,那些类不可以注入。
@Import: 快速的给容器中导入组件
@Import:容器中会自动注册该组件,id 默认是全类名;
注解参数:
class数组:把所有的class全部导入到ioc容器中。
ImportSelector:返回需要导入的组件的全类名数组,组件名为全类名;
ImportBeanDefinitionRegistrar:手动注册 Bean 到容器中,可以自定义组件名。
ImportSelector:需要编写一个类,实现ImportSelector 接口,实现方法
public class MyImportSelector implements ImportSelector {
/**
*AnnotationMetadata :可以获取到标注了 @Import 注解类的所有注解信息;
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[0];
}
}
ImportBeanDefinitionRegistrar:可以自定义注册到ioc容器中组件的名称
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param importingClassMetadata 获取到标注了@Import注解的所有信息
* @param registry BeanDefinition 注册类: 调用它的 registerBeanDefinition 方法将需要添加到容器中的 Bean 手工注册进来;
* RootBeanDefinition:跟容器
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("id", new RootBeanDefinition(xxx.class));
}
}
}
@ImportResource
可以通过这个注解,把我们编写的spring的xml文件导入到javaconfig中,然后根据javaconfig的格式解析。
适用于xml项目转为注解项目时使用
@ConfigurationProperties(profix=“xxx”)
可以通过配置文件的方式,给javabean赋值,只要我们的配置文件中有以xxx开头的配置,就会给这个javabean中名称相同的属性名自动绑定赋值。
这个绑定的配置文件只能时application.properties文件
要赋值的javabean必须在ioc容器中存在
properties文件:
person.name=张三
person.age=19
javaBean类:
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
//...省略getset等方法
}
结果:
这样就会自动绑定配置文件了,一定咬注意,这个javabean必须要存在于ioc容器中,才会绑定。
还可以配合:
@EnableConfigurationProperties()+ @ConfigurationProperties注解使用。
@EnableConfigurationProperties(xxx.class): 作用:
1.把xxx.class加载进ioc容器中
2.开启xxx的绑定数据功能