Spring常用注解(绝对经典)
org.springframework
spring-context
4.3.12.RELEASE
设置类为配置类
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String str : beanDefinitionNames) {
System.out.println(str);
}
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
为配置类开启组件扫描
@ComponentScan(value = "com.atguigu")
@Configuration
@ComponentScan(value = "com.atguigu",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes ={Controller.class,Service.class} )
})
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
包含
包含使用includeFilter,包含里面需要设置使用默认规则为false
@Configuration
@ComponentScan(value = "com.atguigu",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes ={Controller.class,Service.class} )},useDefaultFilters = false)
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
还可以设置按给定类型过滤
@Configuration
@ComponentScan(value = "com.atguigu",includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes ={Controller.class,Service.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
classes ={BookService.class})
},useDefaultFilters = false)
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
其他可以设置的过滤方式还可以有:
自定义过滤规则
public class MyTypeFilter implements TypeFilter {
/*
metadataReader:读取到的当前正在扫描的类的信息
metadataReaderFactory:可以获取到其他任何类的信息
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类的注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类的资源(类的路径)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println(resource);
System.out.println(className);
if(className.contains("er")){
return true;
}
return false;
}
}
设置自定义规则
@Configuration
@ComponentScan(value = "com.atguigu",includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM,
classes = {MyTypeFilter.class})
},useDefaultFilters = false)
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
测试代码
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String str : beanDefinitionNames) {
System.out.println(str);
}
}
测试结果
测试规则打印内容
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/bean/Person.class]
com.atguigu.bean.Person
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/config/MyTypeFilter.class]
com.atguigu.config.MyTypeFilter
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/controller/BookController.class]
com.atguigu.controller.BookController
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/dao/BookDAO.class]
com.atguigu.dao.BookDAO
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/service/BookService.class]
com.atguigu.service.BookService
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/test/MainTest.class]
com.atguigu.test.MainTest
测试类打印过滤结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
myTypeFilter
bookController
bookService
将类配置为Controller类
将类配置为service类
将类配置为dao操作的类
将类配置为通用类组件
调整bean的作用域范围,默认单实例,可以修改为多实例
Bean是默认单实例的,通过指明prototype(多实例)和singleton(单实例)属性指明是否单实例
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
//Bean是默认单实例的,通过指明prototype(多实例)和singleton(单实例)属性指明是是否单实例
//prototype:多实例
//singleton:单实例
//request:同一次请求创建一个实例
//session:同一个session创建一个实例
@Scope("prototype")
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
}
测试
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Object bean1 = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean1==bean2);
}
测试结果为false
实例默认在容器创建时立即加载
使用@Lazy后,当需要创建实例时才被加载
public Person(String name, Integer age) {
System.out.println("给容器添加Person对象");
this.name = name;
this.age = age;
}
测试代码
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器已创建完成");
//没有获取类的代码,单实际上类的实例已经被加载进容器了
}
测试结果
给容器添加Person对象
容器已创建完成
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
}
测试代码
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器已创建完成");
Object bean1 = applicationContext.getBean("person");//这一句出现后才加载Person类
}
测试结果
给容器添加Person对象
容器已创建完成
//判断是否是Linux系统的条件
//要作为自定义条件,要实现Condition接口,并实现match方法
//AnnotatedTypeMetadata:注释信息
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//判断linux洗洗
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获得当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取到bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
String OSproperty = environment.getProperty("os.name");
if (OSproperty.contains("Mac OS X")){
return true;
}
return false;
}
}
另一个自定义条件
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
//获取操作系统信息
String OSproperty = environment.getProperty("os.name");
if (OSproperty.contains("Window")){
return true;
}
return false;
}
}
配置类信息
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试类信息
@Test
public void testBeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
//获取ioc容器的运行环境
ConfigurableEnvironment environment=applicationContext.getEnvironment();
//获取操作系统名称
String property = environment.getProperty("os.name");
System.out.println(property);
String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
for (String name:namesForType) {
System.out.println(name);
}
}
测试结果
Mac OS X
person
female
4.使用ImportBeanDefinitionRegistrar
5.使用Spring提供的FactoryBean(工厂bean)注册组件
1)默认获得的是工厂bean调用getObject创建的对象
2)要获取工厂bean本身,需要给id前面加一个&标识
使用@Import快速为配置类导入一个bean类
可以同时导入多个bean类
需要再配置类上方书写
public class Color {
}
public class Red {
}
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class})//在这里进行快速地导入,可以是数组形式
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试类代码
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void testImport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
person
female
创建需要被导入的类
public class Blue {
}
public class Yellow {
}
创建自己的Import类
public class MyImportSelect implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//返回值是要导入到容器中的组件全类名
//annotationMetadata:注解信息
return new String[]{"com.atguigu.bean.Blue", "com.atguigu.bean.Yellow"};
}
}
在配置类中设置@Import导入的自定义类选择器
注意:@Import({Color.class, Red.class,MyImportSelect.class})
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class,MyImportSelect.class})
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试代码
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void testImport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
Color,Red,Blue,Yellow都有了
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
person
female
自定义导入的类定义,需要实现ImportBeanDefinitionRegistrar接口,并重写 registerBeanDefinitions方法
创建一个需要被注入的类
public class RainBow {
}
创建自定义的注册类信息类
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
//annotationMetadata:当前类的注解信息
//beanDefinitionRegistry:beanDefinition注册类
//把所有需要添加到容器中的bean,调用beanDefinitionRegistry.registerBeanDefinition手动注册类
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
boolean red = beanDefinitionRegistry.containsBeanDefinition("com.atguigu.bean.Red");//判断定义中是否有红色
boolean blue = beanDefinitionRegistry.containsBeanDefinition("com.atguigu.bean.Blue");//判断定义中是否有蓝色
if(red && blue){
//指定bean名
RootBeanDefinition rainbowDefinition = new RootBeanDefinition(RainBow.class);
//注册了一个bean,并指定了一个类名(别名)
beanDefinitionRegistry.registerBeanDefinition("rainbow", rainbowDefinition);
}
}
}
在配置类中进行配置
注意:@Import({Color.class, Red.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试类
@Test
public void testImport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
显示了rainbow
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
person
female
rainbow
创建自定义工厂类,实现FactoryBean接口,并改写一下方法
getObject() //返回工厂生产的类对象
getObjectType()//返回工厂生产的类类型
isSingleton() //返回单例
创建自定义工厂类
这里实现FactoryBean接口,实现三个方法,注意泛型中使用Color类
public class ColorFactory implements FactoryBean {
//返回一个Color对象,这个对象会添加到容器中
@Override
public Color getObject() throws Exception {
System.out.println("color factory generate a instance");
return new Color();
}
@Override
public Class> getObjectType() {
return Color.class;
}
@Override
public boolean isSingleton() {
//true:返回单例,在容器中保存一份
//false:返回多份类实例,每次获取工厂bean都会创建一个新的对象
return false;
}
}
在配置类中定义这个类组件
注意:
@Bean
public ColorFactory colorFactoryBean(){
return new ColorFactory();
}
}
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
@Bean
public ColorFactory colorFactoryBean(){
return new ColorFactory();
}
}
测试类
public class MainTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void testImport(){
printBeans(applicationContext);
//工厂bean获取的是调用的是getObject创建的对象(Color类)
Object bean1 = applicationContext.getBean("colorFactoryBean");
Object bean2 = applicationContext.getBean("colorFactoryBean");
System.out.println(bean1);
System.out.println(bean2.getClass());//class com.atguigu.bean.Color
System.out.println(bean1==bean2);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
person
female
colorFactoryBean
rainbow
color factory generate a instance
color factory generate a instance
com.atguigu.bean.Color@79c97cb
class com.atguigu.bean.Color
false