Spring 依赖注入(DI)的注解

Spring中想要使用注解进行依赖注入,需要进行如下配置:

<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/>
</beans>

 

Spring自带依赖注入的注解

@Required,该注解必须用是setter方法上面,目的是强制要求提供setter所需数据,否则报错。

例如,BeanA中的字段field,有一个setField( T field)方法。当在该方法上使用了@Required之后,在XML中创建BeanA时就必须给出设置field所需的数据。

如下所示:

package o1.bean;

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

public class BeanA {
    private String message;

    public String getMessage(){
        return message;
    }

    @Required //只能放在setter上,在XML配置BeanA时必须指定setter注入,否则在Spring容器启动时将抛出异常
    public void setMessage(String message){
        this.message = message;
    }
}
<?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-3.0.xsd">

    <!--开启注解支持-->
    <context:annotation-config/>


    <bean class="o1.bean.BeanA">
        <!--因为有了@Required,所以这里必须提供,否则报错-->
        <property name="message" ref="message"/>
    </bean>

    <bean name="message" class="java.lang.String">
        <constructor-arg index="0" value="hello world"/>
    </bean>

</beans>
package o1;

import o1.bean.BeanA;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class A {
    private ApplicationContext applicationContext;

    @Before
    public void setUp(){
        applicationContext=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    }

    @Test
    public void run1(){
        BeanA bean = applicationContext.getBean(BeanA.class);
        System.out.println(bean.getMessage());
    }

}

 

@Autowired(required=true)

自动注入,required=true的作用与@Required相同。

可用于构造器、字段、方法。

默认根据参数类型自动装配,但必须只能有一个候选项(required=false则可以允许0个候选项)。

 

@Value(value="SpEL")

可用于字段、方法(@Autowired method)。

如:

@Value(value="#{message}")
private String message;
@Autowired
public void initMessage(@Value(value = "#{message}") String message) {
    this.message = message;
}

 

@Qualifier(value="限定标识符")

可用于方法、字段、参数。

配合@Autowired使用,可用于多个候选项的情况。

 实例如下:

package o1.bean;


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

import javax.sql.DataSource;

public class BeanB {
    private DataSource dataSourceA;
    private DataSource dataSourceB;


    public DataSource getDataSourceA(){
        return dataSourceA;
    }

    @Autowired
    public void initDataSource(@Qualifier( "mysqlDataSource2" ) DataSource dataSource){ //
        this.dataSourceA =dataSource;
    }

    public DataSource getDataSourceB(){
        return dataSourceB;
    }

    @Autowired
    public void setDataSourceB(@Qualifier( "mysqlDataSource1" ) DataSource dataSourceB){
        this.dataSourceB = dataSourceB;
    }
}
<?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-3.0.xsd">

    <!--开启注解支持-->
    <context:annotation-config/>
    <context:property-placeholder location="db.properties"/>

    <bean class="o1.bean.BeanB"/>

    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <qualifier type="org.springframework.beans.factory.annotation.Qualifier" value="mysqlDataSource1"/> <!--type可以省略-->
        <property name="driverClassName" value="${driverClass}"/>
        <property name="url" value="${jdbcUrl_1}"/>
        <property name="username" value="${user}"/>
        <property name="password" value="${password}"/>
    </bean>

    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <qualifier type="org.springframework.beans.factory.annotation.Qualifier" value="mysqlDataSource2"/>
        <property name="driverClassName" value="${driverClass}"/>
        <property name="url" value="${jdbcUrl_2}"/>
        <property name="username" value="${user}"/>
        <property name="password" value="${password}"/>
    </bean>

</beans>
package o1;

import o1.bean.BeanB;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class B {
    private ApplicationContext applicationContext;

    @Before
    public void setUp(){
        applicationContext=new ClassPathXmlApplicationContext("classpath:applicationContextB.xml");
    }

    @Test
    public void run1(){
        BeanB bean = applicationContext.getBean(BeanB.class);
        System.out.println(bean.getDataSourceA());
        System.out.println(bean.getDataSourceB());

    }
}

db.properties

driverClass=com.mysql.jdbc.Driver
jdbcUrl_1=jdbc\:mysql\://localhost\:3306/testdb1?useUnicode=true&amp;characterEncoding=UTF8
jdbcUrl_2=jdbc\:mysql\://localhost\:3306/testdb2?useUnicode=true&amp;characterEncoding=UTF8
user=root
password=root

 

如果有几个常用的DataSource,那么可以自定义注解来使用,而不必每次都是@Qualifier("xx")。如下:

自定义@MySQL和@Oracle

package o1.customize_qualifier;

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

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target( {ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE} )
@Retention( RetentionPolicy.RUNTIME )
@Qualifier
public @interface MySQL {
}
package o1.customize_qualifier;

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

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target( {ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE} )
@Retention( RetentionPolicy.RUNTIME )
@Qualifier
public @interface Oracle {
}

使用qualifier来限定需要注入的bean:

<?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-3.0.xsd">

    <!--开启注解支持-->
    <context:annotation-config/>

    <bean class="o1.bean.BeanC"/>

    <bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <qualifier type="o1.customize_qualifier.MySQL" value="mysqlDataSource"/><!--value可以省略-->
    </bean>

    <bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <qualifier type="o1.customize_qualifier.Oracle" value="oracleDataSource"/>
    </bean>

</beans>

要被注入的bean:

package o1.bean;


import o1.customize_qualifier.MySQL;
import o1.customize_qualifier.Oracle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.sql.DataSource;

public class BeanC {
    private DataSource dataSourceA;
    private DataSource dataSourceB;

    @Autowired
    public void initDataSource(@MySQL DataSource dataSourceA, @Oracle DataSource dataSourceB){
        this.dataSourceA = dataSourceA;
        this.dataSourceB = dataSourceB;
    }

    public DataSource getDataSourceA(){
        return dataSourceA;
    }

    public DataSource getDataSourceB(){
        return dataSourceB;
    }

}

测试:

package o1;

import o1.bean.BeanB;
import o1.bean.BeanC;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.sql.DataSource;

public class C {
    private ApplicationContext applicationContext;

    @Before
    public void setUp(){
        applicationContext=new ClassPathXmlApplicationContext("classpath:applicationContextC.xml");
    }

    @Test
    public void run1(){
        BeanC bean = applicationContext.getBean(BeanC.class);
        DataSource dataSource1 = applicationContext.getBean("dataSource1", DataSource.class);
        DataSource dataSource2 = applicationContext.getBean("dataSource2", DataSource.class);

        Assert.assertEquals(dataSource1, bean.getDataSourceA());
        Assert.assertEquals(dataSource2, bean.getDataSourceB());
    }
}

 

 ==================================================

使用<context:annotation-config/>标签来开启注解形式的依赖注入。

使用<context:component-scan/>标签来表示需要要自动注册Bean定义,而通过base-package属性指定扫描的类路径位置。

注意,<context:component-scan/>默认开启了annotation-config。

使用<aop:aspectj-autoproxy/>标签开启Spring对@AspectJ风格切面的支持。

 

 @AspectJ风格的切面可以通过@Compenent注解标识其为Spring管理Bean,而@Aspect注解不能被Spring自动识别并注册为Bean,必须通过@Component注解来完成。

 

Spring零散所得

 

<<<未完待续>>>

 声明:源自张开涛的Spring教程,再加工。

posted on 2016-05-25 12:23  LarryZeal  阅读(1531)  评论(0编辑  收藏  举报

导航