环境搭建
新建Maven项目spring-annotation-demo,添加Maven依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
1.使用@Configuration和@Bean给容器中注册组件
新建bean包,Person类。三个属性:name,age,nickName。添加有参,无参,toString()方法。
package com.ljessie.bean;
import org.springframework.beans.factory.annotation.Value;
public class Person {
private String name;
private Integer age;
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", nickName='" + nickName + '\'' +
'}';
}
public Person() {
}
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包,MainConfig类。在类名上添加@Configuration,告诉Spring,这是一个配置类;然后新建getPerson()方法,添加@Bean注解
package com.ljessie.config;
import com.ljessie.bean.Person;
import com.ljessie.service.BookService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
/**
* 配置类等同于配置文件
*/
//告诉Spring,这是一个配置类
@Configuration
public class MainConfig {
//给容器中注册一个Bean,类型为返回值的类型,
@Bean(value = "Person")
public Person getPerson(){
return new Person("Bowen",19);
}
}
在src/main/test下,新建测试类IOCTest,新建test01()方法,添加@Test注解。创建annotationConfigApplicationContext 对象加载MainConfig配置类,然后打印容器中定义的
package com.ljessie.test;
import com.ljessie.bean.Person;
import com.ljessie.config.MainConfig;
import com.ljessie.config.MainConfig2;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
public class IOCTest {
@Test
public void test01(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
Person person = (Person) annotationConfigApplicationContext.getBean("Person");
System.out.println(person);
}
运行结果
一月 17, 2020 11:34:44 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@67f89fa3: startup date [Fri Jan 17 11:34:44 CST 2020]; root of context hierarchy
一月 17, 2020 11:34:44 上午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
org.springframework.context.annotation.AnnotationConfigApplicationContext@67f89fa3: startup date [Fri Jan 17 11:34:44 CST 2020]; root of context hierarchy
一月 17, 2020 11:34:44 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3e3047e6: startup date [Fri Jan 17 11:34:44 CST 2020]; root of context hierarchy
一月 17, 2020 11:34:44 上午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
Person
Person{name='Bowen', age=19, nickName='null'}
2.@ComponentScan-自动扫描和指定扫描规则
新建component包,ComponentController添加@Controller,ComponentService添加@Service,ComponentDao添加@Repository。
package com.ljessie.component;
import org.springframework.stereotype.Controller;
@Controller
public class ComponentController {
}
package com.ljessie.component;
import org.springframework.stereotype.Service;
@Service
public class ComponentService {
}
package com.ljessie.component;
import org.springframework.stereotype.Repository;
@Repository
public class ComponentDao {
}
在MainConfig类上面添加@Component注解。@ComponentScan属性:Value,指定要扫描的包;
package com.ljessie.config;
import com.ljessie.bean.Person;
import com.ljessie.component.ComponentService;
import com.ljessie.controller.BookController;
import com.ljessie.service.BookService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
/**
* 配置类等同于配置文件
*/
//告诉Spring,这是一个配置类
@Configuration
//value指定要扫描的包,
// excludeFilters排除要扫描的组件,
// includeFilters只扫描指定的组件,后面要加上useDefaultFilters
@ComponentScan(value = "com.ljessie.component")
public class MainConfig {
//给容器中注册一个Bean,类型为返回值的类型,
@Bean(value = "Person")
public Person getPerson(){
return new Person("Bowen",19);
}
}
运行test01():componentController,componentDao,componentService注册进来了
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
componentController
componentDao
componentService
Person
Person{name='Bowen', age=19, nickName='null'}
includeFilters:只扫描指定的组件,后面要加上useDefaultFilters。可以指定组件的注解,类型和自定义过滤规则。
@ComponentScan(value = "com.ljessie.component"
,includeFilters = {
//指定组件的注解
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class),
//指定组件的类型
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = ComponentService.class),
// 自定义过滤器
// @ComponentScan.Filter(type = FilterType.CUSTOM,classes = CustomFilter.class)
}, useDefaultFilters = false
)
public class MainConfig {
//给容器中注册一个Bean,类型为返回值的类型,
@Bean(value = "Person")
public Person getPerson(){
return new Person("Bowen",19);
}
}
运行test01():只注册了componentController和componentService,componentDao并没有被注册进来。
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
componentController
componentService
Person
Person{name='Bowen', age=19, nickName='null'}
CustomFilter自定义过滤规则,如果组件中包含Controller,则注册。
package com.ljessie.component;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
public class CustomFilter implements TypeFilter {
/**
*
* @param metadataReader 读取到的正在扫描类的信息
* @param metadataReaderFactory 可以获取到的其他类的信息
* @return
* @throws IOException
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类的注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前类的类型信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String className = classMetadata.getClassName();
System.out.println("-------->"+className);
//获取当前类的资源信息(路径等)
metadataReader.getResource();
if(className.contains("Controller")){
return true;
}
return false;
}
}
注掉includeFilters其他指定。
@ComponentScan(value = "com.ljessie.component"
// , excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})}
,includeFilters = {
//指定组件的注解
// @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class),
//指定组件的类型
// @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = ComponentService.class),
// 自定义过滤器
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = CustomFilter.class)
}, useDefaultFilters = false
)
public class MainConfig {
//省略其他代码
}
运行test01():只有componentController被注册进来了
一月 18, 2020 11:27:14 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@475e586c: startup date [Sat Jan 18 11:27:14 CST 2020]; root of context hierarchy
-------->com.ljessie.component.ComponentController
-------->com.ljessie.component.ComponentDao
-------->com.ljessie.component.ComponentService
-------->com.ljessie.component.CustomFilter
一月 18, 2020 11:27:14 上午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
componentController
Person
Person{name='Bowen', age=19, nickName='null'}
excludeFilters:排除要扫描的组件
@ComponentScan(value = "com.ljessie.component"
, excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})}
)
public class MainConfig {
//省略其他代码
}
运行test01():只有componentDao被注册进来了,排除了componentController和componentService。
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
componentDao
Person
Person{name='Bowen', age=19, nickName='null'}
3.@Scope调整作用域
"singleton"; 单例,也是默认值。IOC容器启动会调用方法,创建对象到容器中,以后每次获取,从容器中拿。
"prototype"; 多实例。IOC容器启动,并不会调用方法,创建对象;而是每次获取的时候,才会调用方法,创建对象。
新建MainConfig2
package com.ljessie.config;
import com.ljessie.bean.Color;
import com.ljessie.bean.ColorFactoryBean;
import com.ljessie.bean.Person;
import com.ljessie.bean.Red;
import com.ljessie.condition.LinuxCondition;
import com.ljessie.condition.MyImportBeanDefinitionRegistrar;
import com.ljessie.condition.MyImportSelector;
import com.ljessie.condition.WindowsCondition;
import org.springframework.context.annotation.*;
@Configuration
public class MainConfig2 {
/**
* @Scope:调整作用域
* String SCOPE_SINGLETON = "singleton"; 单例,也是默认值。IOC容器启动会调用方法,创建对象到容器中,以后每次获取,从容器中拿
* String SCOPE_PROTOTYPE = "prototype"; 多实例。IOC容器启动,并不会调用方法,创建对象;而是每次获取的时候,才会调用方法,创建对象。
* @return
*/
@Scope("prototype")
@Bean("zhangsan")
public Person person(){
System.out.println("给容器中添加person....");
return new Person("zhangsan",25);
}
}
在IOCTest里面新建test02()方法
@Test
public void test02(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
System.out.println("容器创建完成");
Person person1 = (Person) annotationConfigApplicationContext.getBean("zhangsan");
Person person2 = (Person) annotationConfigApplicationContext.getBean("zhangsan");
System.out.println(person1 == person2);
}
运行结果:先创建容器,然后调用annotationConfigApplicationContext.getBean()方法时,才会创建Person实例,而且创建的两个实例不是同一对象。
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
zhangsan
容器创建完成
给容器中添加person....
给容器中添加person....
false
4.@Lazy懒加载
单实例bean:默认容器启动时,创建对象;懒加载,在第一次获取对象的时候,创建对象,并进行初始化。
MainConfig2里面person()方法去掉@Scope,添加@Lazy
@Lazy
@Bean("zhangsan")
public Person person(){
System.out.println("给容器中添加person....");
return new Person("zhangsan",25);
}
运行test02()
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
zhangsan
容器创建完成
给容器中添加person....
true
5.@Conditional按照条件注册Bean
新建Condition包,ZhangsanCondition类,实现Condition接口。matches()方法实现匹配逻辑:如果容器中已经包含id为"zhangsan"的bean,则注册当前bean;否则不注册。
package com.ljessie.condition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class ZhangsanCondition implements Condition {
/**
*
* @param context 判断条件使用的上下文环境
* @param metadata 当前注释信息
* @return
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取到IOC使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//获取到类加载器
ClassLoader classLoader = context.getClassLoader();
//获取到环境
Environment environment = context.getEnvironment();
//获取到bean的注册类
BeanDefinitionRegistry registry = context.getRegistry();
//可以判断容器中的注册情况,也可以给容器中注册Bean
//如果容器中包含"zhangsan",则注册;如果不包含,则不注册
boolean containsZhangsan = registry.containsBeanDefinition("zhangsan");
if(containsZhangsan){
return true;
}
// String property = environment.getProperty("os.name");
// if(property.contains("linux")){
// return true;
// }
return false;
}
}
MainConfig2里面添加person02()方法
@Conditional({ZhangsanCondition.class})
@Bean("zhangwu")
public Person person02(){
return new Person("zhangwu",27);
}
运行test02()
@Test
public void test02(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
System.out.println("容器创建完成");
// Person person1 = (Person) annotationConfigApplicationContext.getBean("zhangsan");
// Person person2 = (Person) annotationConfigApplicationContext.getBean("zhangsan");
// System.out.println(person1 == person2);
}
运行结果,"zhangsan"和"zhangwu"都已经被注册到容器中了。
给容器中添加person....
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
zhangsan
zhangwu
容器创建完成
此时注掉MainConfig2里面的person()方法,重新运行test02()。此时"zhangsan"和"zhangwu"都没有被注册到容器中。
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
容器创建完成
6.使用@Import给容器中注册组件
在bean包下,新建Color,Red
package com.ljessie.bean;
public class Color {
}
package com.ljessie.bean;
public class Color {
}
在MainConfig2类上面添加@Import
@Import({Color.class, Red.class})
public class MainConfig2 {
//省略其他代码
}
IOCTest里面新建testImport()方法
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void testImport(){
printBeans(annotationConfigApplicationContext);
//工厂bean获取的是:getObject()创建的对象
//Object colorFactoryBean = annotationConfigApplicationContext.getBean("colorFactoryBean");
//System.out.println(colorFactoryBean.getClass());
}
public void printBeans(AnnotationConfigApplicationContext annotationConfigApplicationContext){
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
运行testImport():Color和Red都已经注册到容器中了。
org.springframework.context.annotation.AnnotationConfigApplicationContext@67f89fa3: startup date [Sat Jan 18 10:49:33 CST 2020]; root of context hierarchy
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.ljessie.bean.Color
com.ljessie.bean.Red
使用ImportSelector注册组件
新建Blue,Yellow类
package com.ljessie.bean;
public class Blue {
}
package com.ljessie.bean;
public class Yellow {
}
新建MyImportSelector,实现ImportSelector方法
package com.ljessie.condition;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* 自定义逻辑,返回需要导入的组件
*/
public class MyImportSelector implements ImportSelector {
/**
*
* @param importingClassMetadata 当前标注@Import注解的类的所有注册信息
* @return 返回值就是导入容器中的组件的全类名,不要返回null
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.ljessie.bean.Blue","com.ljessie.bean.Yellow"};
}
}
MainConfig2里面@Import添加MyImportSelector .class
@Import({Color.class, Red.class, MyImportSelector.class})
public class MainConfig2 {
//省略其他代码
}
运行testImport():Blue和Yellow也注册进来了
org.springframework.context.annotation.AnnotationConfigApplicationContext@67f89fa3: startup date [Sat Jan 18 10:56:22 CST 2020]; root of context hierarchy
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.ljessie.bean.Color
com.ljessie.bean.Red
com.ljessie.bean.Blue
com.ljessie.bean.Yellow
使用ImportBeanDefinitionRegistrar注册组件
新建RainBow类
package com.ljessie.bean;
public class RainBow {
}
新建MyImportBeanDefinitionRegistrar,实现ImportBeanDefinitionRegistrar接口:如果容器中包含Red,则注册RainBow
package com.ljessie.condition;
import com.ljessie.bean.RainBow;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
*
* @param importingClassMetadata:当前类的注册信息
* @param registry:BeanDefinition的注册类,所有要添加到容器中的bean
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean red = registry.containsBeanDefinition("com.ljessie.bean.Red");
if(red){
//指定Bean的定义信息
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
//注册一个Bean
registry.registerBeanDefinition("rainBow", rootBeanDefinition);
}
}
}
MainConfig2类上面,@Import注解添加MyImportBeanDefinitionRegistrar.class
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {
//省略其他代码
}
运行testImport()方法:rainBow注册进来了。
org.springframework.context.annotation.AnnotationConfigApplicationContext@67f89fa3: startup date [Sat Jan 18 11:02:51 CST 2020]; root of context hierarchy
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.ljessie.bean.Color
com.ljessie.bean.Red
com.ljessie.bean.Blue
com.ljessie.bean.Yellow
rainBow
7.使用FactoryBean给容器中注册组件
新建ColorFactoryBean,实现FactoryBean接口
package com.ljessie.bean;
import org.springframework.beans.factory.FactoryBean;
/**
* 创建一个Spring提供的工厂Bean
*/
public class ColorFactoryBean implements FactoryBean<Color> {
/**
*
* @return Color对象,添加到容器中
* @throws Exception
*/
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean----->getObject()");
return new Color();
}
public Class<?> getObjectType() {
return Color.class;
}
public boolean isSingleton() {
return true;
}
}
在MainConfig2里面添加方法
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
修改testImport():
@Test
public void testImport(){
printBeans(annotationConfigApplicationContext);
//工厂bean获取的是:getObject()创建的对象
Object colorFactoryBean = annotationConfigApplicationContext.getBean("colorFactoryBean");
System.out.println(colorFactoryBean.getClass());
}
public void printBeans(AnnotationConfigApplicationContext annotationConfigApplicationContext){
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
运行testImport(),拿到的colorFactoryBean实际是,getObject()方法里返回的Color类型。
org.springframework.context.annotation.AnnotationConfigApplicationContext@67f89fa3: startup date [Sat Jan 18 11:09:11 CST 2020]; root of context hierarchy
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.ljessie.bean.Color
com.ljessie.bean.Red
com.ljessie.bean.Blue
com.ljessie.bean.Yellow
colorFactoryBean
rainBow
ColorFactoryBean----->getObject()
class com.ljessie.bean.Color
组件注册总结
1.包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
2.@Bean[导入的第三方包]
3.@Import
1).@Import(要导入容器的组件)
2).ImportSelector:返回需要导入的组件的全类名数组
3).ImportBeanDefinitionRegistrar:手动注册bean到容器中
4.使用Spring提供的FactoryBean(工厂Bean)
1).默认获取到的是工厂Bean调用getObject()创建的对象
2).要获取工厂Bean本身,需要给id前面加一个&
网友评论