spring注解驱动系列--组件注入

一、spring组件注入的几种方式

1、@Bean[导入的第三方包里面的组件]

2、包扫描+组件标注注解(@ComponentScans/@ComponentScan + @Controller/@Service/@Repository/@Component)

3、@Import[快速给容器中导入一个组件]

4、使用Spring提供的 FactoryBean(工厂Bean)

二、各种方式详解

一、@Bean

一、普通注入

    //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person")
    public Person person01(){
        return new Person("lisi", 20);
    }

 二、条件注入@Conditional

@Conditional注解它的作用是按照一定的条件进行判断,满足条件给容器注册bean。@Conditional只有一个参数,并且这个参数要求是继承与Condition类,并且参数是个数组,也就是可以 传多个的。Condition类是一个函数式接口(只有一个方法的接口被称为函数式接口)。matches方法就是比较方法,如果为true则注入,如果为false则不注入。

@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

栗子: 


//判断是否linux系统
public class LinuxCondition implements Condition {

	/**
	 * ConditionContext:判断条件能使用的上下文(环境)
	 * AnnotatedTypeMetadata:注释信息
	 */
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// TODO是否linux系统
		//1、能获取到ioc使用的beanfactory
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		//2、获取类加载器
		ClassLoader classLoader = context.getClassLoader();
		//3、获取当前环境信息
		Environment environment = context.getEnvironment();
		//4、获取到bean定义的注册类
		BeanDefinitionRegistry registry = context.getRegistry();
		
		String property = environment.getProperty("os.name");
		
		//可以判断容器中的bean注册情况,也可以给容器中注册bean
		boolean definition = registry.containsBeanDefinition("person");
		if(property.contains("linux")){
			return true;
		}
		
		return false;
	}

}

 

	/**
	 * @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean
	 * 
	 * 如果系统是windows,给容器中注册("bill")
	 * 如果是linux系统,给容器中注册("linus")
	 */
	
	@Bean("bill")
	public Person person01(){
		return new Person("Bill Gates",62);
	}	


    @Conditional(LinuxCondition.class)
	@Bean("linus")
	public Person person02(){
		return new Person("linus", 48);
	}

 二、包扫描+组件标注注解

一、@ComponentScans可以配置多个@ComponentScan

二、@ComponentScan 

一、value:指定要扫描的包

二、excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件

三、includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件

四、Filter[]:多个@Filter

五、@Filter:

       1、type:

                FilterType.ANNOTATION:按照注解
                FilterType.ASSIGNABLE_TYPE:按照给定的类型;
                FilterType.ASPECTJ:使用ASPECTJ表达式
                FilterType.REGEX:使用正则指定
                FilterType.CUSTOM:使用自定义规则

        2、classes={Controller.class}:指定过滤的类

@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class})
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})

public class MyTypeFilter implements TypeFilter {

	/**
	 * metadataReader:读取到的当前正在扫描的类的信息
	 * metadataReaderFactory:可以获取到其他任何类信息的
	 */
	@Override
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		// TODO Auto-generated method stub
		//获取当前类注解的信息
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		//获取当前正在扫描的类的类信息
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		//获取当前类资源(类的路径)
		Resource resource = metadataReader.getResource();
		
		String className = classMetadata.getClassName();
		System.out.println("--->"+className);
		if(className.contains("er")){
			return true;
		}
		return false;
	}

}

 三、@Import导入组件

 一、导入对应的类

(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名

@Import({Color.class})

二、ImportSelector:返回需要导入的组件的全类名数组;

@Import({MyImportSelector.class})

//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {

	//返回值,就是到导入到容器中的组件全类名
	//AnnotationMetadata:当前标注@Import注解的类的所有注解信息
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		// TODO Auto-generated method stub
		//importingClassMetadata
		//方法不要返回null值
		return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};
	}

}

三、ImportBeanDefinitionRegistrar:手动注册bean到容器中

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * AnnotationMetadata:当前类的注解信息
	 * BeanDefinitionRegistry:BeanDefinition注册类;
	 * 		把所有需要添加到容器中的bean;调用
	 * 		BeanDefinitionRegistry.registerBeanDefinition手工注册进来
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		
		boolean definition = registry.containsBeanDefinition("全限定类名");
		boolean definition2 = registry.containsBeanDefinition("全限定类名");
		if(definition && definition2){
			//指定Bean定义信息;(Bean的类型,Bean。。。)
			RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
			//注册一个Bean,指定bean名
			registry.registerBeanDefinition("rainBow", beanDefinition);
		}
	}

}

四、 使用Spring提供的 FactoryBean(工厂Bean)

1、默认获取到的是工厂bean调用getObject创建的对象

2、要获取工厂Bean本身,我们需要给id(指的是colorFactoryBean)前面加一个&

	@Bean
	public ColorFactoryBean colorFactoryBean(){
		return new ColorFactoryBean();
	}
	

//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {

	//返回一个Color对象,这个对象会添加到容器中
	@Override
	public Color getObject() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("ColorFactoryBean...getObject...");
		return new Color();
	}

	@Override
	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Color.class;
	}

	//是单例?
	//true:这个bean是单实例,在容器中保存一份
	//false:多实例,每次获取都会创建一个新的bean;
	@Override
	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return false;
	}

}

  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值