Spring组件注册相关注解

组件注册相关注解:相当于xml文档中的标签

示例及运行结果:

@ComponentScan(value = "cn.zsm" , includeFilters = {@Filter(type = FilterType.ANNOTATION , classes = {Controller.class, Service.class})} , useDefaultFilters = false)
@Configuration("config")
public class SpringCondiguration {	
	@Lazy
	@Scope("singleton")
	@Bean(name = "person", initMethod = "m1" , destroyMethod = "m2")
	@Conditional(MethodCondition.class)
	public Person person(){
		return new Person();
	}

	@Scope("prototype")
	@Bean
	@Conditional(MethodCondition.class)
	public Book book(){
		return new Book();
	}					
}

重点看一下@Conditional注解中的MethodCondition.class

public class MethodCondition implements Condition {
	public boolean matches(ConditionContext context,
			AnnotatedTypeMetadata metadata) {
		MultiValueMap<String,Object> attributes = metadata.getAllAnnotationAttributes("org.springframework.context.annotation.Scope");
		Set<String> keySet = attributes.keySet();
		for(String s : keySet){
			List<Object> list = attributes.get(s);
			if("value".equals(s) && "singleton".equals(String.valueOf(list.get(0))))
				return true;			
		}
		return false;
	}
}

运行结果:

各注解的作用:

@Configuration用于类上,标识该类是一个配置类。被该注解标注的类,相当于一个XML配置文件。

@Target(ElementType.TYPE) //作用于类上
@Retention(RetentionPolicy.RUNTIME)  //运行时由JVM保存
@Documented
@Component
public @interface Configuration {
	String value() default "";//指定配置类注册进Spring的bean的名称,默认为类名首字母小写
}

@Bean作用于方法或用于注解类型声明。将方法的返回值注入Spring容器中,默认注入的bean的名称为方法名。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
	@AliasFor("name")  //name属性的别名
	String[] value() default {};  //指定注入Spring容器的bean的名字,数组类型,可以有多个名字

	@AliasFor("value")  //value属性的别名
	String[] name() default {};

	Autowire autowire() default Autowire.NO;  //依赖项是通过基于约定的自动装配按名称或类型注入

	String initMethod() default "";  //指定初始化方法

	String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;   //指定销毁方法
}

@Component 用于类,将标注类注入到Spring容器中。@Controller、@Service等注解都有该注解标注。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
	String value() default ""; //指定注入bean的名称,默认为类名首字母小写
}

@ComponentScan 用于配置类,扫描指定的包,默认会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
	@AliasFor("basePackages")
	String[] value() default {}; //扫描的包的路径,数组类型

	@AliasFor("value")
	String[] basePackages() default {};

	Class<?>[] basePackageClasses() default {};  //指定具体的扫描的类
	
	//bean名称的生成器 默认的是BeanNameGenerator
	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	// 处理检测到的bean的scope范围
	Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
	
	//是否为检测到的组件生成代理
	ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

	//控制符合组件检测条件的类文件   默认是包扫描下的  **/*.class
	String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
	
	//是否对带有@Component @Repository @Service @Controller注解的类开启检测,默认是开启的
	boolean useDefaultFilters() default true;
	//指定包含定义Filter满足条件的组件,还要设置useDefaultFilters = false,关闭默认过滤规则
	Filter[] includeFilters() default {};	
	// 排除某些过来器扫描到的类
	Filter[] excludeFilters() default {};
	//懒加载
	boolean lazyInit() default false;

	@Retention(RetentionPolicy.RUNTIME)
	@Target({})
	@interface Filter {
		
	    /*
             FilterType有5种类型如:
                   ANNOTATION, 注解类型 默认
                   ASSIGNABLE_TYPE,指定固定类
                   ASPECTJ, ASPECTJ类型
                   REGEX,正则表达式
                   CUSTOM,自定义类型
         */
		FilterType type() default FilterType.ANNOTATION; //过滤规则

		@AliasFor("classes")
		Class<?>[] value() default {}; //指定要过滤的类名
		@AliasFor("value")
		Class<?>[] classes() default {};
		//用于过滤器的模式(或多个模式),作为指定类 value 的替代方法。
		String[] pattern() default {};
	}
}

@ComponentScans 用于类,指定多个@ComponentScan策略

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ComponentScans {
	ComponentScan[] value();
}

@Scope 用于类或方法,指定bean的作用域

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
	@AliasFor("scopeName")
	String value() default "";

	/**
	 *prototype 多实例,bean被调用时才被创建
	 *singleton 单例,默认容器启动时创建
	 *request 同一个请求一个实例
	 *session 同一个session一个实例
	 */
	@AliasFor("value")
	String scopeName() default "";

	//指定组件是否应配置为作用域代理,如果是,则该代理应基于接口还是基于子类
	ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}

@Lazy 可用于类、方法、构造函数、参数、属性,懒加载即使用时再对标注的信息进行初始化

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {
	boolean value() default true;
}

@Conditional 用于类或方法 ,根据自定义的条件动态的选择是否加载该bean到springIOC容器中。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional { 
	Class<? extends Condition>[] value(); //指定条件类,继承Condition接口
}


public interface Condition {

	/**
	 * @param context 条件上下文
	 * @param metadata 注释信息
	 * @return true 表示条件通过,注册组件; false条件不通过,结束。
	 */
	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

@Import 用于类,将组件快速导入到组件中

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
	//可导入配置类、ImportSelector接口、ImportBeanDefinitionRegistrar接口、或者常规类组件
	Class<?>[] value(); 
}


public interface ImportSelector {
	/**
	 *返回需要导入容器的全类型信息数组,cn.zsm.entity.Book
	 *AnnotationMetadata:当前标注@import注解的类的所有注解信息
	 */
	String[] selectImports(AnnotationMetadata importingClassMetadata);
}


public interface ImportBeanDefinitionRegistrar {
	/**
	 * AnnotationMetadata:@import注解标注的类的所有注解信息
	 * BeanDefinitionRegistry:BeanDefinition注册类,把需要添加的bean调用
	 *      BeanDefinitionRegistry.registerBeanDefinition手动注册进容器
	 */
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);

}

FactoryBean<T>接口,创建T的实例bean:

public interface FactoryBean<T> {

	T getObject() throws Exception; //获取T实例,将T注入容器

	Class<?> getObjectType();  //返回FactoryBean创建的对象的类型,如果不知道,返回null

	boolean isSingleton();    //是否单例创建T的实例
}

示例:

public class BookFactoryBean implements FactoryBean<Book> {
	public Book getObject() throws Exception {		
		return new Book();
	}

	public Class<?> getObjectType() { 
		return null;
	}

	public boolean isSingleton() { 
		return false;
	}
}


@Configuration
public class SpringCondiguration {	 		
	@Bean
	public BookFactoryBean bookFactoryBean(){
		return new BookFactoryBean();
	}	
}

测试类:

	@Test
	public void test() {
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringCondiguration.class);	
		Object book = applicationContext.getBean("bookFactoryBean");
		Object bookFactory = applicationContext.getBean("&bookFactoryBean"); 
		System.out.println("book的class类型为: "+book.getClass().getName());
		System.out.println("bookFactory的class类型为: "+bookFactory.getClass().getName());		
	}

结果:

从结果中可以看出,@Bean注册进Spring容器的实例名bookBeanFactory,注册的是BookFactoryBean,但是bookBeanFactory的类型确实Book.class。而BookBeanFactory注册进Spring容器的实例为&bookFactoryBean。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值