Spring 6:※ Spring中的注释

ioc中的annotation配置

※ @Autowired
1)、Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。

   

<!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->  
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

       
或者使用下面的隐式注册(隐式注册 post-processors 包括了
 

AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor。)

    <?xml version="1.0" encoding="UTF-8"?>  
    <context:annotation-config/>   
    </beans>  


2)、@Autowired默认按照类型匹配的方式进行注入
3)、@Autowired注解可以用于成员变量、setter方法、构造器函数等
4)、使用@Autowired注解先按照byTYpe查找,如果找到多个,则按照byName的形式查找,否则报错
5)、Spring 允许我们通过 @Qualifier 注释指定注入 Bean 的名称。@Autowired 和 @Qualifier 结合使用时,自动注入的策略变成 byName 了。

   

public class MovieRecommender {  
      
    @Autowired  
    @Qualifier("mainCatalog")  
    private MovieCatalog movieCatalog;  
          
        private CustomerPreferenceDao customerPreferenceDao;  
      
        @Autowired  
        public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {  
            this.customerPreferenceDao = customerPreferenceDao;  
        }  
      
        // ...  
    }  
例:
实体类:

package com.briup.bean;

public class SrcBean {
	private long id;
	
	@Override
	public String toString() {
		return "SrcBean [id=" + id + "]";
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}
}



package com.briup.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class DestBean {
	/*
	 * 注解写在全局变量上是直接赋值
	 * 打破类的私有性
	 */
	@Autowired
	@Qualifier("src")
	private /*@Qualifier("src1")*/SrcBean src;
	
	public DestBean() {
		super();
	}
	@Autowired(required=true)
	public DestBean(@Qualifier("src1")SrcBean src) {
		this.src = src;
	}

	@Override
	public String toString() {
		return "DestBean [src=" + src + "]";
	}

	public SrcBean getSrc() {
		return src;
	}
	/*
	 * @Autowired自动装配
	 * 先基于类型找,如果找到多个
	 * 在基于名字查找(基于名字查找
	 * 是基于参数的变量名字查找)
	 * 
	 * 出现的位置
	 * 1.set方法
	 * 2.全局变量
	 * 3.构造器
	 * @Autowired(required=false)
	 * required为true表示必须的,基于类型
	 * 或者名字一定要找到对象,找不多报错
	 * required为flase,找到装配,找不到忽略
	 * @Qualifier 声明名字,基于名字找到
	 * 位置
	 * 不能写在构造器之上,构造器中参数
	 * 参数声明之前可以写
	 * 
	 * 注意:set方法和构造器和全局变量都写注解
	 * set方法生效
	 * 构造器和全局变量都注解了,
	 * 全局变量生效
	 */
	//@Autowired
//	@Qualifier("src1")
	public void setSrc(/*@Qualifier("src1")*/SrcBean src1) {
		this.src = src1;
	}
}


配置文件xml:

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd
          ">
          <!-- 告诉spring检查单前配置bean标签
          中所有class对应的类是否有
          	@Autowired
          注解
           -->
         <!--  <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
          </bean> -->
          <!-- 让spring检查class中对应的各种注解
           @Autowired  AutowiredAnnotationBeanPostProcessor,
           @Resource @PostConstruct   @PreDestory CommonAnnotationBeanPostProcessor,
            PersistenceAnnotationBeanPostProcessor,
           	@Required RequiredAnnotationBeanPostProcessor
           -->
         <context:annotation-config></context:annotation-config>
         <bean name="dest" 
         	class="com.briup.bean.DestBean" >
         </bean> 
         <bean name="src" 
         	class="com.briup.bean.SrcBean">
         	<property name="id" value="100"></property>
         </bean> 
         <bean name="src1" 
         	class="com.briup.bean.SrcBean">
         	<property name="id" value="101"></property>
         </bean> 
</beans>



测试代码:

@Test
	public void annotation_test(){
		try {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/IOC/annotation.xml");
		System.out.println(cp.getBean("dest"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

※ @Resource
1)、@Resource 的作用相当于 @Autowired,只不过 @Autowired 按 byType 自动注入,
@Resource 默认按 先用byName,如果找不到合适的就再用byType来注入.
2)、要让 JSR-250(@Resource属于这种注解 ) 的注释生效,除了在 Bean 类中标注这些注释外,
还需要在 Spring 容器中注册一个负责处理这些注释的 BeanPostProcessor

    <bean  class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>   
3)、@Resource 有两个属性是比较重要的,分别是 name 和 type,Spring 将 @Resource 注释的 name 属性解析为 Bean 的名字,而 type 属性则解析为 Bean 的类型。所以如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略。如果既不指定 name 也不指定 type 属性,这时将通过反射机制使用 byName 自动注入策略。
   

 public class SimpleMovieLister {   
        private MovieFinder movieFinder;    
       @Resource  
        public void setMovieFinder(MovieFinder movieFinder) {  
            this.movieFinder = movieFinder;  
        }  
    }  

※ @PostConstruct 和 @PreDestroy
标注了 @PostConstruct 注释的方法将在类实例化后调用,而标注了 @PreDestroy 的方法将在类销毁之前调用。
   

public class CachingMovieLister {  
      
        @PostConstruct  
        public void populateMovieCache() {  
            // populates the movie cache upon initialization...  
        }  
          
        @PreDestroy  
        public void clearMovieCache() {  
            // clears the movie cache upon destruction...  
        }  
    }  


※ @Component
1)、使用@Component注解可以直接定义Bean,而无需在xml定义。但是若两种定义同时存在,xml中的定义会覆盖类中注解的Bean定义。
2)、@Component 有一个可选的入参,用于指定 Bean 的名称。

   

 @Component  
    public class ActionMovieCatalog implements MovieCatalog {  
        // ...  
    }  


3)、<context:component-scan/> 允许定义过滤器将基包下的某些类纳入或排除。Spring 支持以下 4 种类型的过滤方式:
(不要求)
过滤器类型    表达式范例
annotation    org.example.SomeAnnotation
assignable    org.example.SomeClass
regex            org\.example\.Default.*
aspectj         org.example..*Service+

下面这个XML配置会忽略所有的@Repository注解
   

<beans ...>  
      
         <context:component-scan base-package="org.example">  
            <context:include-filter type="regex" expression=".*Stub.*Repository"/>  
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>  
         </context:component-scan>  
      
    </beans>


4)、默认情况下通过 @Component 定义的 Bean 都是 singleton 的,如果需要使用其它作用范围的 Bean,可以通过 @Scope 注释来达到目标,其默认作用域是"singleton",如果要换成其他作用区域,直接后面添加类型即可比如 @Scope("prototype") ,spring2.0后 又增加了request ,session和global session 4个作用区域
  

  @Scope("prototype")  
    @Component  
    public class MovieFinderImpl implements MovieFinder {  
        // ...  
    }  


5)、Spring 2.5以后引入了更多典型化注解(stereotype annotations): @Component、@Service和 @Controller。 @Component是所有受Spring管理组件的通用形式; 而@Repository、@Service和 @Controller则是@Component的细化, 用来表示更具体的用例(例如,分别对应了持久化层、服务层和表现层)
  

  @Service  
    public class SimpleMovieLister {  
      
        private MovieFinder movieFinder;  
      
        @Autowired  
        public SimpleMovieLister(MovieFinder movieFinder) {  
            this.movieFinder = movieFinder;  
        }  
    }  
      
    @Repository  
    public class JpaMovieFinder implements MovieFinder {  
        // implementation elided for clarity  
    }  


6)、要检测这些类并注册相应的bean,需要在XML中包含以下元素,其中'basePackage'是两个类的公共父包 (或者可以用逗号分隔的列表来分别指定包含各个类的包)。

   

<?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"  
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
           xmlns:context="http://www.springframework.org/schema/context"  
           xsi:schemaLocation="http://www.springframework.org/schema/beans   
               http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
               http://www.springframework.org/schema/context  
               http://www.springframework.org/schema/context/spring-context-3.2.xsd">  
                     
         <context:component-scan base-package="org.example"/>
    </beans>  

此外,在使用组件扫描元素时,AutowiredAnnotationBeanPostProcessor 和CommonAnnotationBeanPostProcessor会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。

例:
实体类:

package com.briup.bean;

import javax.annotation.PreDestroy;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

//@Component
@Repository("src")
public class SrcBean {
	/*
	 * 基本数据类型或者字符串
	 * set方法上赋值
	 * 全局变量
	 */
//	@Value("101");
	//@Value(value="101")
	private long id;
	
	public SrcBean() {
	}
	
	public SrcBean(long id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return "SrcBean [id=" + id + "]";
	}

	public long getId() {
		return id;
	}
	@Value("101")
	public void setId(long id) {
		this.id = id;
	}
	@PreDestroy
	public void destory(){
		System.out.println("destory...222.");
	}
}



package com.briup.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
/*
 * @Component让spring构建单前对象
 * 相当与在配置文件中配置了bean标签
 * @Component("dest") 参数是给当前对象
 * 起名字
 * 默认名字类名,类名首字母大写
 * 默认名字类名首字母小写
 * 类名第一个第二个字母大写,
 * 默认名字全类名
 * @Scope("")两个
 * 	singleton
 * 	prototype 非单列
 * 	request 每次请求构建一个对象
 * 	session
 * 	global session
 * @Component细分,区分web项目
 * 层次用的
 * @Controller web层
 * @Service 业务逻辑层service
 * @Repository数据持久层dao
 */
//@Component("dest")
//@Scope("prototype")
//@Component(value="dest")
//@Controller("dest")
@Service("dest")
//@Repository
public class DestBean {
	
	/*
	 * 注解写在全局变量上是直接赋值
	 * 打破类的私有性
	 */
//	@Autowired
//	@Qualifier("src1")
	@Resource
	private /*@Qualifier("src1")*/SrcBean src;
	/*
	 * 对象构建初始化的方法
	 */
	@PostConstruct
	public void init_test(){
		System.out.println("init....");
	}
	/*
	 * 对象销毁的时候的方法
	 * (本质从spring容器中移除的时候)
	 * 该方法的执行保证当前对象是单列
	 */
	@PreDestroy
	public void destory(){
		System.out.println("destory1111....");
	}
	public DestBean() {
		super();
	}
//	@Autowired(required=true)
	public DestBean(/*@Qualifier("src1")*/ SrcBean src) {
		this.src = src;
	}

	@Override
	public String toString() {
		return "DestBean [src=" + src + "]";
	}

	public SrcBean getSrc() {
		return src;
	}
	/*
	 * @Autowired自动装配
	 * 先基于类型找,如果找到多个
	 * 在基于名字查找(基于名字查找
	 * 是基于参数的变量名字查找)
	 * 
	 * 出现的位置
	 * 1.set方法
	 * 2.全局变量
	 * 3.构造器
	 * @Autowired(required=false)
	 * required为true表示必须的,基于类型
	 * 或者名字一定要找到对象,找不多报错
	 * required为flase,找到装配,找不到忽略
	 * @Qualifier 声明名字,基于名字找到
	 * 位置
	 * 不能写在构造器之上,构造器中参数
	 * 参数声明之前可以写
	 * 
	 * 注意:set方法和构造器和全局变量都写注解
	 * set方法生效
	 * 构造器和全局变量都注解了,
	 * 全局变量生效
	 * @Resource也是完成自动注入对象
	 * 默认是基于名字查找对象,名字
	 * 按照类型找,
	 * 位置:
	 * 	set方法上 名字是set方法去掉set
	 * 首字母小写
	 * @Resource(name="src")
	 * name属性基于名字查找,找不到
	 * 报错
	 * @Resource(type=SrcBean.class)
	 * 基于类型去找
	 * 注意:即声明type类型查找,同时
	 * set方法去掉set首字母小写的名字
	 * xml文件有bean对象,按名字查找
	 * @Resource(name="src",type=SrcBean.class)
	 * name属性和type属性并存的时候
	 * 基于名字开始找,名字如果找不到
	 * 直接报错
	 */
//	@Autowired()
//	@Qualifier("src1")
//	@Resource
//	@Resource(name="src")
	//@Resource(name="src",type=SrcBean.class)
	public void setSrc3(/*@Qualifier("src1")*/SrcBean src3) {
		this.src = src3;
	}
}



配置文件xml:

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd
          ">
          <!-- 告诉spring检查单前配置bean标签
          中所有class对应的类是否有
          	@Autowired
          注解
           -->
         <!--  <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
          </bean> -->
          <!-- 让spring检查class中对应的各种注解
           @Autowired  AutowiredAnnotationBeanPostProcessor,
           @Resource @PostConstruct   @PreDestory CommonAnnotationBeanPostProcessor,
            PersistenceAnnotationBeanPostProcessor,
           	@Required RequiredAnnotationBeanPostProcessor
           -->
        <!--  <context:annotation-config></context:annotation-config> -->
        	<!-- 扫描含有注解的类 
        	base-package指向含有注解类的包
        	如果多个包有注解,逗号隔开-->
        	<context:component-scan 
        	base-package="com.briup.bean,com.briup.pojo">
        		<!-- 扫描包含哪些注解,一般不写 -->
        		<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        		<!-- 忽略注解 
        		type 属性是annotation 
        			expression注解的全限定名
        		type属性是assignable
        			扫描类的全限定名
        		type属性是regex 正则表达式
        		type属性是aspectj aspectj语句
        		-->
        		<!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> -->
        		<context:exclude-filter type="assignable" 
        		expression="com.briup.bean.SrcBean"/>
        	</context:component-scan>
<!--          <bean name="dest" 
         	class="com.briup.bean.DestBean" >
         </bean> 
         <bean name="src" 
         	class="com.briup.bean.SrcBean">
         	<property name="id" value="100"></property>
         </bean> 
         <bean name="src1" 
         	class="com.briup.bean.SrcBean">
         	<property name="id" value="101"></property>
         </bean>  -->
</beans>



测试代码:

@Test
	public void annotation_test(){
		try {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/IOC/annotation.xml");
		DestBean db=
				(DestBean) cp.getBean("dest");
		System.out.println(db);
		cp.destroy();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_42857603/article/details/83279050
今日推荐