[译]16-spring基于注解的配置元数据

从spring2.5起spring框架开始支持java注解的配置元数据.所以除了使用xml配置文件来描述bean的装配之外,你还

可以使用基于java注解的配置元数据来完成同样的功能。

 

spring框架最终装配bean的时候会首先根据注解配置元数据来装配,然后再按照xml配置文件来装配。这也就意味着

xml配置文件的配置信息会覆盖掉注解的配置信息。

 

spring容器默认情况下没有开启基于注解的装配。如果要使用基于java注解的元数据,我们需要首先在xml文件中引

入context命名空间.然后使用<context:annotation-config/>元素开启spring的注解配置元数据.模板如下:

<?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.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   <!-- bean definitions go here -->

</beans>

 

下面我们分小节介绍常用的每个注解:

Required注解

该注解标注到bean的setter上,意味着bean的该属性必须由spring进行注入。如果没有注入的话,spring容器在启动

的时候就会报错.我们来看一个例子帮助理解:

1.新建包com.tutorialspoint.annotation.required,并在包中新建People.java和Address.java.内容如下:

//People.java

package com.tutorialspoint.annotation.required;

import org.springframework.beans.factory.annotation.Required;

public class People {

    private Address home;
    private Address company;
    
    //标注Required注解的属性,必须由spring容器注入,否则会报错
    @Required
    public void setHome(Address home) {
        this.home = home;
    }
    public void setCompany(Address company) {
        this.company = company;
    }
    
    public void print(){
        System.out.println("home: "+home);
        System.out.println("company: "+company);
    }
}


//Address.java

package com.tutorialspoint.annotation.required;

public class Address {

}

 

2.在src目录下新建annotation_required.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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   
   <bean id="home" class="com.tutorialspoint.annotation.required.Address"></bean>
   <bean id="company" class="com.tutorialspoint.annotation.required.Address"></bean>

   <bean id="people" class="com.tutorialspoint.annotation.required.People">
       <!-- home属性必须注入,否则spring在启动的时候会报错 -->
       <property name="home" ref="home"></property>
   </bean>
   
</beans>

 

3.在com.tutorialspoint.annotation.required包中新建MainApp.java.内容如下:

package com.tutorialspoint.annotation.required;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {

    public static void main(String[] args) {
        
        ApplicationContext context = new ClassPathXmlApplicationContext("annotation_required.xml");
        
        People people = (People) context.getBean("people");
        
        people.print();
    }
}

 

4.运行程序,检查结果:

如果我们没有注入home属性,会得到如下错误:

Property 'home' is required for bean 'people'

 

Autowired和Qualifier注解

Autowired可以标注在字段、setter、构造函数上。默认是按类型进行装配。具体的工作流程如下:

1.如何一个字段、属性、构造方法被Autowired标注,spring在容器中相应的类型的bean

2.如果找不到对应类型的bean,直接报错

3.如果找到了多个该类型的bean,会按照名字进行装,如果无法按照名字装配则报错

 

通过配合使用Qualifier注解,可以使Autowired注解一开始就按照名字进行装配

 

下面来看个例子:

1.新建包com.tutorialspoint.annotation.autowired.并在包中新建People.java和Address.java,内容如下:

//People.java

package com.tutorialspoint.annotation.autowired;

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

public class People {
    
    //家庭地址
    private Address home;
    //公司地址
    private Address company;
    
    /**
     * @Autowired的注解还可以标注在字段上,如下
     */
    //现住地址
    @Autowired
    @Qualifier(value="live")
    private Address live;
    
    public People(){}
    
    /**
     * Autowired的注解还可以标注在构造函数上。
     */
    @Autowired
    public People(Address home){
        this.home=home;
    }
    
    /**
     * Autowired注解可以标注在setter方法上.被该注解标注的setter默认情况
     * 下是必须由spring注入的,可以用@Autowired(required=false)写法覆盖
     * 默认行为
     * 
     * Autowired注解默认按照类型进行装配.不过配合Qualifier使用可以达到按照名字进行匹配的目的
     * 其中@Qualifier的value属性用来指明依赖bean的名字
     * 
     */
    @Autowired
    @Qualifier(value="company")
    public void setCompany(Address company) {
        this.company = company;
    }
    public void setLive(Address live) {
        this.live = live;
    }
    
    public void print(){
        System.out.println("home: "+home);
        System.out.println("company: "+company);
        System.out.println("live: "+live);
    }
    
    
}


//Address.java

package com.tutorialspoint.annotation.autowired;

public class Address {

    private String content;

    public void setContent(String content) {
        this.content = content;
    }
    
    @Override
    public String toString() {
        return content;
    }
}

 

2.在src目录下新建配置文件annotation_autowired.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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   
   <bean id="home" class="com.tutorialspoint.annotation.autowired.Address">
      <property name="content" value="home"></property>
   </bean>
   <bean id="company" class="com.tutorialspoint.annotation.autowired.Address">
      <property name="content" value="company"></property>
   </bean>
   <bean id="live" class="com.tutorialspoint.annotation.autowired.Address">
      <property name="content" value="live"></property>
   </bean>
   
   <bean id="people" class="com.tutorialspoint.annotation.autowired.People">
   </bean>
   
</beans>

 

3.在com.tutorialspoint.annotation.autowired包中新建MainApp.java,内容如下:

package com.tutorialspoint.annotation.autowired;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {

    public static void main(String[] args) {
        
        ApplicationContext context = new ClassPathXmlApplicationContext("annotation_autowired.xml");
        
        People people = (People)context.getBean("people");
        
        people.print();
    }
}

 

4.运行程序,检查结果:

 

JSR-250注解

jsr-250提供了三个注解:PostConstruct、PreDestroy、Resource

PostConstruct相当于之前介绍的init-method属性,指定bean的初始化方法

PreDestroy相当于之前介绍的destroy-method属性,指定bean的销毁方法

Resource类似于Autowired注解,不过Resource是由jdk提供了,Autowired是spring提供的。

 

Resource直接默认情况下先按照名字进行注入,如果在容器中找不到相应的名字,就会按照类型装配,看个例子:

1.新建包com.tutorialspoint.annotation.jsr250,并在包中新建People.java和Address.java,内容如下:

//People.java

package com.tutorialspoint.annotation.jsr250;

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

public class People {
    
    private Address home;
    
    public People(){}
    public People(Address home){
        this.home=home;
    }
    
    @PostConstruct
    public void init(){
        System.out.println("init invoked ... ");
    }
    
    @PreDestroy
    public void destroy(){
        System.out.println("destroy is invoked ... ");
    }

    @Resource
    public void setHome(Address home) {
        this.home = home;
    }
    
    public void print(){
        System.out.println("address: "+home);
    }
}


//Address.java

package com.tutorialspoint.annotation.jsr250;

public class Address {

    private String content;

    public void setContent(String content) {
        this.content = content;
    }
    
    @Override
    public String toString() {
        return content;
    }
}

 

2.在src目录下新建annotation_jsr250.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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   
   <bean id="home" class="com.tutorialspoint.annotation.jsr250.Address">
     <property name="content" value="home"></property>
   </bean>   
   
   <bean id="people" class="com.tutorialspoint.annotation.jsr250.People"></bean>
   
</beans>

 

3.在包com.tutorialspoint.annotation.jsr250中新建MainApp.java.内容如下:

package com.tutorialspoint.annotation.jsr250;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {

    public static void main(String[] args) {
        
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("annotation_jsr250.xml");
        
        People people = (People) context.getBean("people");
        
        people.print();
        
        context.registerShutdownHook();
        
    }
}

4.运行程序,检查结果:

posted @ 2015-05-08 09:42  sysman  阅读(501)  评论(0编辑  收藏  举报