1.JSR250标准注解
(使用Java定义bean) 1.概念: 1.首先,在全局配置文件加入Classpath等扫描的配置,然后再加入元数据的支持 接着,通过注解,扫描会自动识别Bean并把其加入到applicationContext(IOC容器) 最后,其它的类拿取applicationContext.getBean()方法就能生成对象实例等资源 简单的说,是一种在Spring注入的基础上的升级版,相比而言,省去了许多xml的配置 2.Classpath扫描与组件管理 从Spring3.0开始,Spring JavaConfig项目提供了很多特性,包括使用Java而不是xml定义bean,比如 @Configuration、@Bean、@Import、@DependsOn @Component(一个通用注解,可用于任何bean) 有针对性的注解 @Repository(通常用于注解Dao类,即持久层) @Service(通常用于注解Service类,即服务层) @Controller(通常用于Controller类,即控制层) 3.元注解 (Meta-annotations) 1.概念: 许多Spring提供的注解可以作为自己的代码,即“元数据注解” 它是一个很简单的注解,可以应用到另一个注解 4.类的自动检测及bean的注册 1.类的注解 @Repository。。。。 2.方法/属性的注解 @Autowired 5.xml配置 1.通过在基于xml的Spring配置如下标签(请注意包含上下文命名空间,即最顶端的配置) <context:annotation-config/>仅会查找同一个applicationContext中的bean注解 2.类的自动检测及bean的注册 <context:component-scan> 它包含了<context:annotation-config/>的功能,所以使用前者就不使用后者了 两者区别: <context:component-scan>扫描整个类的注解 <context:annotation-config/>在注解到了bean之后,才能扫描该类的方法/成员变量的注解 6.使用过滤器进行自定义扫描 1.默认情况下,类被自动发现并注册bean的条件: 使用@Component、@Repository、@Service、@Controll注解 或者使用@Component的自定义注解 2.使用过滤器修改默认情况 如:xml配置忽略@Repository注解bean,用“Stub”代替 <beans> <context:component-scan base-package="com.nan.service"> <context:include-filter type="regex" expression=".*Stub.*Repository" /> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" /> </context:component-scan> </beans> 1.type的类型 annotation、regex、assignable、aspectj、custom 7.定义bean 扫描过程中组件被自动检测,然后,bean的名称是由BeanNameGenerator接口生成的 1.可以显示的设置beanName(@Component、@Repository、@Service、@Controll都有name属性) 2.自定义beanName 1.实现BeanNameGenerator接口 (要求:一定要包含一个无参构造函数) 2.在xml自动检测扫描加入指定自定义bean名称的类路径,如下 <beans> <context:component-scan base-package="com.nan.service" name-generator=“com.nan.MyBeanNameGenerator” /> </beans> 8.作用域 1.默认情况下,自动查找的Spring组件,其scope是singleton Spring2.5提供了一个标识scope的注解@Scope(没有显示的写出名字时,默认是这个类的类名首字母小写) 2.自定义scope策略 1.实现ScopeNetadataResolver接口 (要求:一定要包含一个无参构造函数) 2.在xml自动检测扫描加入指定自定义scope的类路径,如下 <beans> <context:component-scan base-package="com.nan.service" name-generator=“com.nan.MyScopeNetadataResolver” /> </beans> 9.代理方式 可以使用scoped-proxy属性指定代理方式 参数:no、interfaces、targetClass 配置: <beans> <context:component-scan base-package="com.nan.service" scoped-proxy=“interfaces” /> </beans> 10.@Required (不常用) 1.作用: 1.适用于bean属性的setter()方法 2.仅仅表示,受影响的bean属性必须在配置时被填充 通过在bean定义/自动装配一个明确的属性值 简而言之: (类似设置注入) 在加载bean容器注入到IOC容器时,通过@Required注解到属性的setter()上,给属性赋值 例子: @Required public void setName(String name){ this.name = name; } 11.@Autowired (类似@Required,不同:不仅仅用于setter()方法上) 1.可以注解在“传统”的setter方法 2.可以注解在构造器/成员变量 例子: 1.@Autowired private String name; 2.@Autowired public Class(String name){ this.name = name; } 3.注意 1.默认情况下,如果找不到合适的bean(无值)将会导致autowiring失败抛出异常,可以通过以下方式避免 @Autowired(required=true) 2.每个类只能有一个构造器被标记为required=true 4.可以注解在接口(实际上也是注解在成员变量,即把容器的值赋予) ApplicationContext、BeanFactory、Environmrnt、ResourceLoader、。。。。(众所周知的解析依赖性接口) 例子: @Autowired private ApplicationContext context; (直接取得IOC容器的全局上下文) 5.可以注解在集合(实际上也是注解在成员变量,即集合内的object赋值) (Set、List、Map(Map的key要为String类型,目的是beanName同时赋值进来)Set和List只是把bean对象赋予) 1.集合有序的实现方式 1.实现org.springframeworkframework.core.Ordered接口 2.@Order注解 (类上面注解) 单个值:@Order(1) 多个值:@Order(value=1、value=2、。。。) 对Map无效(因为Map根据key来取值) 2.例子: @Autowired private List<object> list; 6.不可以注解 1.BeanPostProcessor 2.BeanFactoryPostProcessor 3.原因: @Autowired是由Spring BeanPostProcessor处理的,所以不能在自定义的BeanPostProcessor BeanFactoryPostProcessor 4.能注解的方式 1.xml 2.Spring的@Bean注解加载 简而言之: 就是把自定义的类注入(添加)到Spring容器,也让Spring来处理 7.@Qualifier 1.按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一) 也可以用于指定单独的构造器参数/方法参数 2.可以用于注解集合类型变量 简而言之: 当@autowired注解的bean有多个的时候,用@Autowired缩小注解的范围,使之更准确 3.xml配置(另一种注入方式) <bean class="com.nan.className"> <qualifier value="name" /> </bean> 4.如果通过名字进行注解注入,主要使用的不是@Autowired(即使在技术能够通过@Qualifier指定bean名字) (替代方式:JSR-250@Resource注解) 例子: (比如:两个bean当中,指明引用哪个) 1.@Autowired @Qualifier(“name”) private String name; 2.@Autowired public void name(@Qualifier(“name”)String name){ 。。。。。 } 5.自定义 1.手动例子: 1.@Qualifier public interface Genre{ 。。。 } 2.@Genre(“name”) private String name; 2.xml例子 <bean id="" clsss=""> <qualifier type="Genre" value="name" /> </bean> 8.@Resource (不从属于@Autowired,只是拿来与@Qulifier作比较,即不和@Autowired结合使用) 1.概念: 通过独特的名称来定义识别特定的目标 (这是一个与所声明的类型无关的匹配过程) 2.通过唯一的名称引用集合/Map的bean (因语义差异,集合/Map类型的bean无法通过@Autowired来注入; 因为没有类型匹配到这样的bean) 3.可用于变量/setter() 4.属性 1.name();被Spring默认作为beanName的名称 1.如果没有显示指定@Resource的name,默认名称是从属性名/setter()方法得出 2.beanName解析原理: 由ApplicationContext中的CommonAnnotationBeanPostProcessor发现并处理的 1.@PostConstructs (Spring2.5中引入支持的初始化回调) 2.@PreDestroy (Spring2.5中引入支持的销毁回调) 前提: 在Spring的ApplicationContext注册CommonAnnotationBeanPostProcessor 例子: @PostConstructs public void construct(){ 。。。 } 例子: @Resource(name=“beanName”) 9.@Qualifier和@Resource的区别 1.@Autowired适用于fields、constructs、multi-argument、methods 这些允许在参数级别使用@Qualifier注解缩小范围的情况 2.@Resource 适用于成员变量、只有一个参数的setter方法, 所以在目标是构造/一个多参数方法时,最好的方式是使用@Qualifier?????????????????? 简而言之: 两者都是用来缩小@Autowired的自动装配方式 1.前者是在多个的装配时使用 2.后者是指定一个特定的bean给其值 12.@Bean (类似xml配置文件的<bean />) 1.用于标识一个配置和初始化一个由SpringIOC容器管理的新对象,类似xml配置文件的<bean /> 2.可以在Spring的@Component注解的类中使用@Bean注解任何方法,该方法返回对象(通常配合使用的是@Configuration) 3.属性 name(默认情况,name为方法名的名称)、init-method、destroy-method 例子: @Configuration public class name{ @Bean/@Bean(name=“。。”) public Object name(){ return new name();对象 } } 13.@ImportResource和@Value 用来读取配置文件 (前者类似xml导入配置文件:<context:property-placeholder location="classpath://jdbc.properties" />) (后者类似xml导入配置文件的值:<property name=“url” value=“${jdbc.url}” />。。。。) 1.例子: @Configuration @ImportResource("classpath://jdbc.properties") public class name{ @Value(“${jdbc.url}”) private String url; @Bean/@Bean(name=“。。”) public Object name(){ return new name(url);对象 } } 14.@Bean和@Scope (类似xml的作用域) 1.默认为单例 2.@Scope的属性,proxyMode = ScopeProxyMode.TARGET_CLASS(代理方式) 15.基于泛型的自动装配 (即在自动装配的时候,加个泛型,来区别对应的bean) 例子: 1. 1.@Bean public StringStore stringStore(){ } @Bean public IntrgerStore integerStore(){ } 2.@Autowired private Store<String> s1;(对应上面的第一个bean) @Autowired private Store<Integer> s1; 2.List<Store<String>>