IOC_组件注册的几种方法
前置测试用例
//a.自定义注册类MySpringIocConfig
//注解配置类
@Configuration
public class MySpringIocConfig{
}
//b.通过 new AnnotationCofigApplicationContext(MySpringIocConfig.class)获取配置类之注册的组件
//获取Spring上下文ApplicationContext,全文中获取注册的bean
public class IocTest{
@Test
public void test(){
//获取上下文
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MySpringIocConfig.class);
//获取全文注册的组件的名称
String[] strs=applicationContext.getBeanDefinitionNames();
}
}
@ComponentScan
-配置类上使用
普通使用
多用于自编写类的组件的注册,例如扫描dao和service包下的使用了@Component等注解的类,注册到容器中。
- 将要给IOC容器管理的bean的类上,添加注解[@Service@Component@Repository@Controller]
- 在配置类上,添加注解@ComponentScan(value={“com.gh.dao”,”com.gh.service”})
@Configuration
@ComponentScan(value={"com.gh.service","com.gh.dao"})
public class MySpringIocConfig{
}
高级使用
@ComponentScan 注解配置FilterType过滤器,过滤掉一些bean使其不注册
自定义TypeFilter对组件进行过滤
//使用FilterType,过滤注册的组件
//编写配置类,加上@ComponentScan注解
//includeFilters =>只包含,配合UseDefaultFilters=false
//excludeFilters =>不包含,配置FilterType
@Configuration
@ComponentScan(
value={"com.gh"},
includeFilters={
@ComponentScan.Filter(type=FilterType.ANNOTATION,value=Component.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value = Apple.class),
@ComponentScan.Filter(type = FilterType.CUSTOM,value = MyTypeFilter.class)
},
useDefaultFilters = false
)
public class MySpringIocConfig{
}
//编写TypeFilter实现类,内部编写过滤逻辑
public class MyTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取环境信息
Resource resource = metadataReader.getResource();
//返回true,则通过过滤;
return false;
}
}
spring提供的Filter组件过滤器
//① 只包含的Filters,userDefaulters=false
@ComponentScan(
value={"com.gh"},
includeFilters={
@ComponentScan.Filter(type=Filter.ANNOTATION,value=Component.class),
@ComponentScan.Filter(type=FIlter.CUATOM,value=MyTypeFilter.class),
@ComponentScan.FIlter(type=Filter.ASSIGNABLE,value=Person.class)
},
userDefaultFilter=false
)
//②不包含
@ComponentScan(
value={"com.gh"},
excludeFilters={
@ComponentScan.Filter(type=Filter.ANNOTATION,value=Component.class),
@ComponentScan.Filter(type=FIlter.CUATOM,value=MyTypeFilter.class),
@ComponentScan.FIlter(type=Filter.ASSIGNABLE,value=Person.class)
},
userDefaultFilter=false
)
//其中FilterType是一个枚举类型,有5个类型
@Bean
-配置类内的方法上使用
普通用法
第三方的组件包,我们无法入侵代码,在类上加注解;使用在配置类中配置第三方bean,以让IOC容器管理第三方bean
- 编写配置类MySpringIocConfig
- 在配置类中,添加方法且方法上添加@Bean注解
@Configuration
public class MySpringIocCOnfig{
//可以通过applicationContext.getBean("person"),获取该注册的组件
@Bean
public Person person(){
retrun new Person("张三");
}
//可以通过applicationContext.getBean("person1"),获取该注册的组件
@Bean
public Person person1(){
return new Person("李四");
}
//可以通过applicationContext.getBean("personY"),获取该注册的组件
@Bean("personY")
public Person personX(){
return new Person("王五");
}
//配置组件的作用范围
//singleton 单例(默认值)-每次容器获取的都是同一个对象
//prototype 多例-每次容器获取组件,都init一个新的对象
//request web中-每次一个新的请求,注册一次组件
//session web中-每次一个新的session,init一个新的组件
@Bean
@Scope("prototype")
public Apple apple(){
return new Apple();
}
// 每次获取IOC容器获取orange组件时,采取注册bean;在IOC容器初始化时,不注册bean;
@Bean
@Lazy
public Orange orange(){
return new Orange();
}
}
高级用法
注册实现了FactoryBean接口的工厂bean
// 编写工程类,实现FactoryBean接口
public class AppleFactoryBean implements FactoryBean<Apple> {
@Override
public Apple getObject() throws Exception {
return new Apple();
}
@Override
public Class<?> getObjectType() {
return Apple.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
//配置类中注册AppleFactoryBean
@Configuration
public class MySpringIocCofig{
@Bean
public AppleFactoryBean appleFactoryBean(){
return new AppleFactoryBean();
}
}
//获取注册的组件
public class MainTest{
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MySpringIocConfig.class);
//获取工厂类注册的bean =>返回的时apple
applicationContext.getBean("appleFactoryBean");
//获取工厂类本身 =>返回的是appleFactoryBean
applicationContext.getBean("&appleFactoryBean");
}
}
@Import
-配置类上使用
直接导入类或者自定义类的导入规则类
编写配置类,添加@Import
注解
//配置类
@Configuration
@Import({Color.class,Orange.class})
public class MySpringIocConfig(){
}
//可以通过全类名获取组件
public class MainTest{
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MySpringIocConfig.class);
applicationContext.getBean("com.gh.pojo.Color");
}
}
编写实现了ImportSelector
接口的实现类
//配置类
@Configuration
@Import({MyImportSelector.class})
public class MySpringIocConfig(){
}
//实现了ImportSelector接口的实现类,返回一个String[],内的string要写全类名
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.gh.pojo.Fruit","cpm.gh.pojo.Apple"};
}
}
//可以通过全类名获取组件
public class MainTest{
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MySpringIocConfig.class);
applicationContext.getBean("com.gh.pojo.Fruit");
}
}
编写实现了ImportBeanDefinitionRegistry
接口的实现类
//编写配置类
@Configuration
@Import({MyImportBeabDefinitionRegistry.class})
public class MySpringIocConfig{
}
//实现ImportBeanDefinitionRegistry的实现类
public class MyImportBeanDefinitionRegistry implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(Apple.class);
registry.registerBeanDefinition("golphin",beanDefinition);
}
}
//通过golphin获取组件
public class MainTest{
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicatinContext(MySpringIocCOnfig.class);
application.getBean("golphin");//获取到了apple组件
}
}
@Conditional
按照条件配置bean
@Conditional 可以放在方法上,也可以放在类上
@Conditional value中的class是=>实现了Condition接口的实现类
放在配置类注册bean的方法上时 => bean注册时,若能满足条件,才能够从IOC容器中获取;
放在配置类打上方时 => 配置类下注册的bean,要满足条件才能够获取到;
//操作系统时Windows
public class ConditionWindows implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String osName=context.getEnvironment().getProperty("os.name");
if(osName.toLowerCase().contains("windows")){
return true;
}
return false;
}
}
//操作系统时Linux
public class ConditionLinux implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String osName=context.getEnvironment().getProperty("os.name");
if(osName.toLowerCase().contains("linux")){
return true;
}
return false;
}
}
//编写配置类
@Configuration
@ComponentScan({"com.gh"})
@Conditional(ConditionWindows.class)
public class MySpringIocConfig{
@Bean
public Apple apple(){
return new Apple();
}
@Bean
@Conditonal(ConditionLinux.class)
public Orange orange(){
return new Orange();
}
}