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&characterEncoding=UTF8 jdbcUrl_2=jdbc:mysql://localhost:3306/testdb2?useUnicode=true&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教程,再加工。