五 Spring常用注解,自动扫描装配Bean
spring自动扫描机制
spring2.5为我们引入了组件自动扫描机制,它可以在classPath路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。
也就是要spring自动扫描机制只会查找指定类路径下包含@Component、@Service、@Controller、@Repository这四种注解的类。
要使用自动扫描机制,我们需要打开以下配置信息:
1、引入context命名空间 需要在xml配置文件中配置以下信息: 同上先引入context 命名空间,同时
2、在配置文件中添加context:component-scan标签
<context:component-scan base-package="*"/>
其中base-package为需要扫描的包(含子包)。
注:
1、在使用组件扫描元素时,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。也就是说如果使用了context:component-scan标签,就可以不需要再引入context:annotation-config标签
<context:component-scan />还允许定义过滤器将基包下的某些类纳入或排除。Spring支持以下4种类型的过滤方式:
过滤器类型 表达式范例 说明
注解 org.example.SomeAnnotation 将所有使用SomeAnnotation注解的类过滤出来
类名指定 org.example.SomeClass 过滤指定的类
正则表达式 com\.kedacom\.spring\.annotation\.web\..* 通过正则表达式过滤一些类
AspectJ表达式 org.example..*Service+ 通过AspectJ表达式过滤一些类
以正则表达式为例,我列举一个应用实例:
Java代码
<context:component-scan base-package="com.casheen.spring.annotation">
<context:exclude-filter type="regex" expression="com\.casheen\.spring\.annotation\.web\..*" />
</context:component-scan>
<context:component-scan base-package="com.casheen.spring.annotation">
<context:exclude-filter type="regex" expression="com\.casheen\.spring\.annotation\.web\..*" />
</context:component-scan>
值得注意的是<context:component-scan
/>配置项不但启用了对类包进行扫描以实施注释驱动Bean定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),因此当使用<context:component-scan
/>后,就可以将<context:annotation-config />移除了。
六 常用注解
--定义Bean的注解
@Controller
@Controller("Bean的名称")
定义控制层Bean,如Action
@Service
@Service("Bean的名称")
定义业务层Bean
@Repository
@Repository("Bean的名称")
定义DAO层Bean
@Component
定义Bean, 不好归类时使用.
--自动装配Bean (选用一种注解就可以)
@Autowired (Srping提供的)
默认按类型匹配,自动装配(Srping提供的),可以写在成员属性上,或写在setter方法上
@Autowired(required=true)
一定要找到匹配的Bean,否则抛异常。 默认值就是true
@Autowired
@Qualifier("bean的名字")
按名称装配Bean,与@Autowired组合使用,解决按类型匹配找到多个Bean问题。
@Resource JSR-250提供的
默认按名称装配,当找不到名称匹配的bean再按类型装配.
可以写在成员属性上,或写在setter方法上
可以通过@Resource(name="beanName") 指定被注入的bean的名称, 要是未指定name属性, 默认使用成员属性的变量名,一般不用写name属性.
@Resource(name="beanName")指定了name属性,按名称注入但没找到bean, 就不会再按类型装配了.
@Inject 是JSR-330提供的
按类型装配,功能比@Autowired少,没有使用的必要。
--定义Bean的作用域和生命过程
@Scope("prototype")
值有:singleton,prototype,session,request,session,globalSession
@PostConstruct
相当于init-method,使用在方法上,当Bean初始化时执行。
@PreDestroy
相当于destory-method,使用在方法上,当Bean销毁时执行。
--声明式事务
@Transactional
六 配置工厂Bean
通常由应用程序直接使用new创建新对象,为了将对象的创建与使用相分离,采用工厂模式,即应用程序将对象的创建与初始化交给工厂来完成。
一般情况下,应用程序有自己的工厂对象来创建bean,如果将工厂对象交给Springle管理,那么Spring管理的就不是普通的bean,而是工厂Bean。调用getBean()方法,Spring返回的不是直接创建的Bean的实例,而是由工厂创建的Bean实例。
一般在Spring中配置工廠Bean,有3中不同類型的工廠Bean的配置.
1.静态工厂 創建具體Bean實例的是靜態方法
[java] view plain copy
- import java.util.Random;
- public class Static FactoryBean{
- public static
- Integer createRandom() {
- return new
- Integer(new Random().nextInt());
- }
- }
將其納入Spring容器來管理,需要通過factory-method指定静态方法名称,方法必须是static的,才能找到。
[java] view plain copy
[java] view plain copy
- <bean id="random"
- class="example.chapter3.StaticFactoryBean"
- factory-method="createRandom"//createRandom方法必須是static的,才能找到
- scope="prototype"
- />
測試:
[java] view plain copy
- public static void main(String[] args) {
- XmlBeanFactory factory = new XmlBeanFactory(new
- ClassPathResource("config.xml"));
- System.out.println(factory.getBean("random").toString());
- //StaticFactoryBean sfb =
- (StaticFactoryBean)factory.getBean("random");
- //System.out.println(sfb.createRandom().toString());
- //調用getBean()時,返回隨機數.如果沒有指定factory-method,會返回StaticFactoryBean的實例,即返回工廠Bean的實例
- }
2.实例工厂 創建具體Bean實例的是實例,不是靜態方法
[java] view plain copy
- import java.text.SimpleDateFormat;
- import java.util.Date;
- public class InstanceFactoryBean {
- private String format = "yy-MM-dd HH:mm:ss";
- public void setFormat(String format) {
- this.format = format;
- } public String createTime() {
- return new SimpleDateFormat(format).format(new Date());
- }
- }
配置文件需要配置兩個bean:第一個Bean和普通的Bean沒有區別,第二個bean定義如何通過工廠Bean獲取Bean,需要指定工廠Bean的名稱和方法名稱
[java] view plain copy
- <bean id="instanceFactoryBean" class="example.chapter3.InstanceFactoryBean">
- "format" value="yyyy-MM-dd HH:mm:ss"/>
- </bean>
- <bean id="currentTime" factory-bean="instanceFactoryBean" factory-method="createTime"/>
測試:
[java] view plain copy
- public static void main(String[] args) {
- XmlBeanFactory factory = new XmlBeanFactory(new
- ClassPathResource("config.xml"));
- System.out.println(factory.getBean("currentTime"));
- }
3.實現FactoryBean接口
[java] view plain copy
- public class PiFactoryBean implements FactoryBean {
- public Object getObject() throws Exception {
- return new Double(3.14159265358979);
- } public Class getObjectType() {
- return Double.class;
- } public boolean isSingleton() {
- return true;
- } }
實現了FactoryBean接口的Bean,不再被視爲普通的Bean.Spring會自動檢測.
[java] view plain copy
- <bean id="pi"class="example.chapter3.PiFactoryBean"/>
測試
[java] view plain copy
- public static void main(String[] args) throws Exception {
- XmlBeanFactory factory = new XmlBeanFactory(new
- ClassPathResource("config.xml"));
- System.out.println(factory.getBean("pi"));//返回PiFactoryBean
- 的工廠方法getObject返回的Double對象實例
- //PiFactoryBean p =
- (PiFactoryBean)factory.getBean("&pi");
- //加"&"返回工廠Bean的實例.
- //System.out.println(p.getObject());
- }