- 浏览: 21542450 次
- 性别:
-
博客专栏
-
-
跟我学spring3
浏览量:2425660
-
-
Spring杂谈
浏览量:3014769
-
-
跟开涛学SpringMVC...
浏览量:5644298
-
-
Servlet3.1规范翻...
浏览量:261151
-
-
springmvc杂谈
浏览量:1599534
-
-
hibernate杂谈
浏览量:250880
-
-
跟我学Shiro
浏览量:5865894
-
-
跟我学Nginx+Lua开...
浏览量:703932
-
-
亿级流量网站架构核心技术
浏览量:788036
文章分类
- 全部博客 (329)
- 跟我学Nginx+Lua开发 (13)
- 跟我学spring (54)
- 跟开涛学SpringMVC (34)
- spring4 (16)
- spring杂谈 (50)
- springmvc杂谈 (22)
- 跟我学Shiro (26)
- shiro杂谈 (3)
- hibernate杂谈 (10)
- java开发常见问题分析 (36)
- 加速Java应用开发 (5)
- Servlet 3.1规范[翻译] (21)
- servlet3.x (2)
- websocket协议[翻译] (14)
- websocket规范[翻译] (1)
- java web (6)
- db (1)
- js & jquery & bootstrap (4)
- 非技术 (4)
- reminder[转载] (23)
- 跟叶子学把妹 (8)
- nginx (2)
- 架构 (19)
- flume架构与源码分析 (4)
最新评论
-
xxx不是你可以惹得:
认真看错误代码,有时候重启电脑就行了 醉了 我把数据库配置写死 ...
第十六章 综合实例——《跟我学Shiro》 -
dagger9527:
holyselina 写道您前面说到能获取调用是的参数数组,我 ...
【第六章】 AOP 之 6.6 通知参数 ——跟我学spring3 -
xxx不是你可以惹得:
Access denied for user 'root'@' ...
第十六章 综合实例——《跟我学Shiro》 -
dagger9527:
只有@AspectJ支持命名切入点,而Schema风格不支持命 ...
【第六章】 AOP 之 6.5 AspectJ切入点语法详解 ——跟我学spring3 -
dagger9527:
支持虽然会迟到,但永远不会缺席!
【第四章】 资源 之 4.3 访问Resource ——跟我学spring3
12.2 注解实现Bean依赖注入
12.2.1 概述
注解实现Bean配置主要用来进行如依赖注入、生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的数据将覆盖基于注解配置中的依赖注入的数据。
Spring3的基于注解实现Bean依赖注入支持如下三种注解:
- Spring自带依赖注入注解: Spring自带的一套依赖注入注解;
- JSR-250注解:Java平台的公共注解,是Java EE 5规范之一,在JDK6中默认包含这些注解,从Spring2.5开始支持。
- JSR-330注解:Java 依赖注入标准,Java EE 6规范之一,可能在加入到未来JDK版本,从Spring3开始支持;
- JPA注解:用于注入持久化上下文和尸体管理器。
这三种类型的注解在Spring3中都支持,类似于注解事务支持,想要使用这些注解需要在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>
这样就能使用注解驱动依赖注入了,该配置文件位于“resources/ chapter12/dependecyInjectWithAnnotation.xml”。
12.2.2 Spring自带依赖注入注解
一、@Required:依赖检查;
对应于基于XML配置中的依赖检查,但XML配置的依赖检查将检查所有setter方法,详见【3.3.4 依赖检查】;
基于@Required的依赖检查表示注解的setter方法必须,即必须通过在XML配置中配置setter注入,如果没有配置在容器启动时会抛出异常从而保证在运行时不会遇到空指针异常,@Required只能放置在setter方法上,且通过XML配置的setter注入,可以使用如下方式来指定:
@Requried setter方法
1、准备测试Bean
package cn.javass.spring.chapter12; public class TestBean { private String message; @Required public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean" class="cn.javass.spring.chapter12.TestBean"> <property name="message" ref="message"/> </bean> <bean id="message" class="java.lang.String"> <constructor-arg index="0" value="hello"/> </bean>
3、测试类和测试方法如下:
package cn.javass.spring.chapter12; //省略import public class DependencyInjectWithAnnotationTest { private static String configLocation = "classpath:chapter12/dependecyInjectWithAnnotation.xml"; private static ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocation); //1、Spring自带依赖注入注解 @Test public void testRequiredForXmlSetterInject() { TestBean testBean = ctx.getBean("testBean", TestBean.class); Assert.assertEquals("hello", testBean.getMessage()); } }
在XML配置文件中必须指定setter注入,否则在Spring容器启动时将抛出如下异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testBean' defined in class path resource [chapter12/dependecyInjectWithAnnotation.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'message' is required for bean 'testBean'
二、@Autowired:自动装配
自动装配,用于替代基于XML配置的自动装配,详见【3.3.3 自动装配】。
基于@Autowired的自动装配,默认是根据类型注入,可以用于构造器、字段、方法注入,使用方式如下:
@Autowired(required=true) 构造器、字段、方法
@Autowired默认是根据参数类型进行自动装配,且必须有一个Bean候选者注入,如果允许出现0个Bean候选者需要设置属性“required=false”,“required”属性含义和@Required一样,只是@Required只适用于基于XML配置的setter注入方式。
(1)、构造器注入:通过将@Autowired注解放在构造器上来完成构造器注入,默认构造器参数通过类型自动装配,如下所示:
1、准备测试Bean,在构造器上添加@AutoWired注解:
package cn.javass.spring.chapter12; import org.springframework.beans.factory.annotation.Autowired; public class TestBean11 { private String message; @Autowired //构造器注入 private TestBean11(String message) { this.message = message; } //省略message的getter和setter }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean11" class="cn.javass.spring.chapter12.TestBean11"/>
3、测试类如下:
@Test public void testAutowiredForConstructor() { TestBean11 testBean11 = ctx.getBean("testBean11", TestBean11.class); Assert.assertEquals("hello", testBean11.getMessage()); }
在Spring配置文件中没有对“testBean11”进行构造器注入和setter注入配置,而是通过在构造器上添加@ Autowired来完成根据参数类型完成构造器注入。
(2)、字段注入:通过将@Autowired注解放在构造器上来完成字段注入。
1、准备测试Bean,在字段上添加@AutoWired注解:
package cn.javass.spring.chapter12; import org.springframework.beans.factory.annotation.Autowired; public class TestBean12 { @Autowired //字段注入 private String message; //省略getter和setter }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean12" class="cn.javass.spring.chapter12.TestBean12"/>
3、测试方法如下:
@Test public void testAutowiredForField() { TestBean12 testBean12 = ctx.getBean("testBean12", TestBean12.class); Assert.assertEquals("hello", testBean12.getMessage()); }
字段注入在基于XML配置中无相应概念,字段注入不支持静态类型字段的注入。
(3)、方法参数注入:通过将@Autowired注解放在方法上来完成方法参数注入。
1、准备测试Bean,在方法上添加@AutoWired注解:
package cn.javass.spring.chapter12; import org.springframework.beans.factory.annotation.Autowired; public class TestBean13 { private String message; @Autowired //setter方法注入 public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } }
package cn.javass.spring.chapter12; //省略import public class TestBean14 { private String message; private List<String> list; @Autowired(required = true) //任意一个或多个参数方法注入 private void initMessage(String message, ArrayList<String> list) { this.message = message; this.list = list; } //省略getter和setter }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean13" class="cn.javass.spring.chapter12.TestBean13"/> <bean id="testBean14" class="cn.javass.spring.chapter12.TestBean14"/> <bean id="list" class="java.util.ArrayList"> <constructor-arg index="0"> <list> <ref bean="message"/> <ref bean="message"/> </list> </constructor-arg> </bean>
3、测试方法如下:
@Test public void testAutowiredForMethod() { TestBean13 testBean13 = ctx.getBean("testBean13", TestBean13.class); Assert.assertEquals("hello", testBean13.getMessage()); TestBean14 testBean14 = ctx.getBean("testBean14", TestBean14.class); Assert.assertEquals("hello", testBean14.getMessage()); Assert.assertEquals(ctx.getBean("list", List.class), testBean14.getList()); }
方法参数注入除了支持setter方法注入,还支持1个或多个参数的普通方法注入,在基于XML配置中不支持1个或多个参数的普通方法注入,方法注入不支持静态类型方法的注入。
注意“initMessage(String message, ArrayList<String> list)”方法签名中为什么使用ArrayList而不是List呢?具体参考【3.3.3 自动装配】一节中的集合类型注入区别。
三、@Value:注入SpEL表达式;
用于注入SpEL表达式,可以放置在字段方法或参数上,使用方式如下:
@Value(value = "SpEL表达式") 字段、方法、参数
1、可以在类字段上使用该注解:
@Value(value = "#{message}") private String message;
2、可以放置在带@Autowired注解的方法的参数上:
@Autowired public void initMessage(@Value(value = "#{message}#{message}") String message) { this.message = message; }
3、还可以放置在带@Autowired注解的构造器的参数上:
@Autowired private TestBean43(@Value(value = "#{message}#{message}") String message) { this.message = message; }
具体测试详见DependencyInjectWithAnnotationTest 类的testValueInject测试方法。
四、@Qualifier:限定描述符,用于细粒度选择候选者;
@Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常,详见【3.3.3 自动装配】中的根据类型进行注入;
@Qualifier限定描述符除了能根据名字进行注入,但能进行更细粒度的控制如何选择候选者,具体使用方式如下:
@Qualifier(value = "限定标识符") 字段、方法、参数
(1)、根据基于XML配置中的<qualifier>标签指定的名字进行注入,使用如下方式指定名称:
<qualifier type="org.springframework.beans.factory.annotation.Qualifier" value="限定标识符"/>
其中type属性可选,指定类型,默认就是Qualifier注解类,name就是给Bean候选者指定限定标识符,一个Bean定义中只允许指定类型不同的<qualifier>,如果有多个相同type后面指定的将覆盖前面的。
1、准备测试Bean:
package cn.javass.spring.chapter12; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; public class TestBean31 { private DataSource dataSource; @Autowired //根据<qualifier>标签指定Bean限定标识符 public void initDataSource(@Qualifier("mysqlDataSource") DataSource dataSource) { this.dataSource = dataSource; } public DataSource getDataSource() { return dataSource; } }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean31" class="cn.javass.spring.chapter12.TestBean31"/>
我们使用@Qualifier("mysqlDataSource")来指定候选Bean的限定标识符,我们需要在配置文件中使用<qualifier>标签来指定候选Bean的限定标识符“mysqlDataSource”:
<bean id="mysqlDataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <qualifier value="mysqlDataSource"/> </bean>
3、测试方法如下:
@Test public void testQualifierInject1() { TestBean31 testBean31 = ctx.getBean("testBean31", TestBean31.class); try { //使用<qualifier>指定的标识符只能被@Qualifier使用 ctx.getBean("mysqlDataSource"); Assert.fail(); } catch (Exception e) { //找不到该Bean Assert.assertTrue(e instanceof NoSuchBeanDefinitionException); } Assert.assertEquals(ctx.getBean("mysqlDataSourceBean"), testBean31.getDataSource()); }
从测试可以看出使用<qualifier>标签指定的限定标识符只能被@Qualifier使用,不能作为Bean的标识符,如“ctx.getBean("mysqlDataSource")”是获取不到Bean的。
(2)、缺省的根据Bean名字注入:最基本方式,是在Bean上没有指定<qualifier>标签时一种容错机制,即缺省情况下使用Bean标识符注入,但如果你指定了<qualifier>标签将不会发生容错。
1、准备测试Bean:
package cn.javass.spring.chapter12; //省略import public class TestBean32 { private DataSource dataSource; @Autowired @Qualifier(value = "mysqlDataSource2") //指定Bean限定标识符 //@Qualifier(value = "mysqlDataSourceBean") //是错误的注入,不会发生回退容错,因为你指定了<qualifier> public void initDataSource(DataSource dataSource) { this.dataSource = dataSource; } public DataSource getDataSource() { return dataSource; } }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean32" class="cn.javass.spring.chapter12.TestBean32"/> <bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"/>
3、测试方法如下:
@Test public void testQualifierInject2() { TestBean32 testBean32 = ctx.getBean("testBean32", TestBean32.class); Assert.assertEquals(ctx.getBean("oracleDataSource"), testBean32.getDataSource()); }
默认情况下(没指定<qualifier>标签)@Qualifier的value属性将匹配Bean 标识符。
(3)、扩展@Qualifier限定描述符注解:对@Qualifier的扩展来提供细粒度选择候选者;
具体使用方式就是自定义一个注解并使用@Qualifier注解其即可使用。
首先让我们考虑这样一个问题,如果我们有两个数据源,分别为Mysql和Oracle,因此注入两者相关资源时就牵扯到数据库相关,如在DAO层注入SessionFactory时,当然可以采用前边介绍的方式,但为了简单和直观我们希望采用自定义注解方式。
1、扩展@Qualifier限定描述符注解来分别表示Mysql和Oracle数据源
package cn.javass.spring.chapter12.qualifier; import org.springframework.beans.factory.annotation.Qualifier; /** 表示注入Mysql相关 */ @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Mysql { }
package cn.javass.spring.chapter12.qualifier; import org.springframework.beans.factory.annotation.Qualifier; /** 表示注入Oracle相关 */ @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Oracle { }
2、准备测试Bean:
package cn.javass.spring.chapter12; //省略import public class TestBean33 { private DataSource mysqlDataSource; private DataSource oracleDataSource; @Autowired public void initDataSource(@Mysql DataSource mysqlDataSource, @Oracle DataSource oracleDataSource) { this.mysqlDataSource = mysqlDataSource; this.oracleDataSource = oracleDataSource; } public DataSource getMysqlDataSource() { return mysqlDataSource; } public DataSource getOracleDataSource() { return oracleDataSource; } }
3、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean33" class="cn.javass.spring.chapter12.TestBean33"/>
4、在Spring修改定义的两个数据源:
<bean id="mysqlDataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <qualifier value="mysqlDataSource"/> <qualifier type="cn.javass.spring.chapter12.qualifier.Mysql"/> </bean> <bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <qualifier type="cn.javass.spring.chapter12.qualifier.Oracle"/> </bean>
5、测试方法如下:
@Test public void testQualifierInject3() { TestBean33 testBean33 = ctx.getBean("testBean33", TestBean33.class); Assert.assertEquals(ctx.getBean("mysqlDataSourceBean"), testBean33.getMysqlDataSoruce()); Assert.assertEquals(ctx.getBean("oracleDataSource"), testBean33.getOracleDataSoruce()); }
测试也通过了,说明我们扩展的@Qualifier限定描述符注解也能很好工作。
前边演示了不带属性的注解,接下来演示一下带参数的注解:
1、首先定义数据库类型:
package cn.javass.spring.chapter12.qualifier; public enum DataBase { ORACLE, MYSQL; }
2、其次扩展@Qualifier限定描述符注解
package cn.javass.spring.chapter12.qualifier; //省略import @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface DataSourceType { String ip(); //指定ip,用于多数据源情况 DataBase database();//指定数据库类型 }
3、准备测试Bean:
package cn.javass.spring.chapter12; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import cn.javass.spring.chapter12.qualifier.DataBase; import cn.javass.spring.chapter12.qualifier.DataSourceType; public class TestBean34 { private DataSource mysqlDataSource; private DataSource oracleDataSource; @Autowired public void initDataSource( @DataSourceType(ip="localhost", database=DataBase.MYSQL) DataSource mysqlDataSource, @DataSourceType(ip="localhost", database=DataBase.ORACLE) DataSource oracleDataSource) { this.mysqlDataSource = mysqlDataSource; this.oracleDataSource = oracleDataSource; } //省略getter方法 }
4、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean34" class="cn.javass.spring.chapter12.TestBean34"/>
5、在Spring修改定义的两个数据源:
<bean id="mysqlDataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <qualifier value="mysqlDataSource"/> <qualifier type="cn.javass.spring.chapter12.qualifier.Mysql"/> <qualifier type="cn.javass.spring.chapter12.qualifier.DataSourceType"> <attribute key="ip" value="localhost"/> <attribute key="database" value="MYSQL"/> </qualifier> </bean> <bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <qualifier type="cn.javass.spring.chapter12.qualifier.Oracle"/> <qualifier type="cn.javass.spring.chapter12.qualifier.DataSourceType"> <attribute key="ip" value="localhost"/> <attribute key="database" value="ORACLE"/> </qualifier> </bean>
6、测试方法如下:
@Test public void testQualifierInject3() { TestBean34 testBean34 = ctx.getBean("testBean34", TestBean34.class); Assert.assertEquals(ctx.getBean("mysqlDataSourceBean"), testBean34.getMysqlDataSource()); Assert.assertEquals(ctx.getBean("oracleDataSource"), testBean34.getOracleDataSoruce()); }
测试也通过了,说明我们扩展的@Qualifier限定描述符注解也能很好工作。
四、自定义注解限定描述符:完全不使用@Qualifier,而是自己定义一个独立的限定注解;
1、首先使用如下方式定义一个自定义注解限定描述符:
package cn.javass.spring.chapter12.qualifier; //省略import @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface CustomQualifier { String value(); }
2、准备测试Bean:
package cn.javass.spring.chapter12; //省略import public class TestBean35 { private DataSource dataSoruce; @Autowired public TestBean35(@CustomQualifier("oracleDataSource") DataSource dataSource) { this.dataSoruce = dataSource; } public DataSource getDataSoruce() { return dataSoruce; } }
3、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean35" class="cn.javass.spring.chapter12.TestBean35"/>
4、然后在Spring配置文件中注册CustomQualifier自定义注解限定描述符,只有注册了Spring才能识别:
<bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"> <property name="customQualifierTypes"> <set> <value>cn.javass.spring.chapter12.qualifier.CustomQualifier</value> </set> </property> </bean>
5、测试方法如下:
@Test public void testQualifierInject5() { TestBean35 testBean35 = ctx.getBean("testBean35", TestBean35.class); Assert.assertEquals(ctx.getBean("oracleDataSource"), testBean35.getDataSource()); }
从测试中可看出,自定义的和Spring自带的没什么区别,因此如果没有足够的理由请使用Spring自带的Qualifier注解。
到此限定描述符介绍完毕,在此一定要注意以下几点:
- 限定标识符和Bean的描述符是不一样的;
- 多个Bean定义中可以使用相同的限定标识符;
- 对于集合、数组、字典类型的限定描述符注入,将注入多个具有相同限定标识符的Bean。
12.2.3 JSR-250注解
一、@Resource:自动装配,默认根据类型装配,如果指定name属性将根据名字装配,可以使用如下方式来指定:
@Resource(name = "标识符") 字段或setter方法
1、准备测试Bean:
package cn.javass.spring.chapter12; import javax.annotation.Resource; public class TestBean41 { @Resource(name = "message") private String message; //省略getter和setter }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean41" class="cn.javass.spring.chapter12.TestBean41"/>
3、测试方法如下:
@Test public void testResourceInject1() { TestBean41 testBean41 = ctx.getBean("testBean41", TestBean41.class); Assert.assertEquals("hello", testBean41.getMessage()); }
使用非常简单,和@Autowired不同的是可以指定name来根据名字注入。
使用@Resource需要注意以下几点:
- @Resource注解应该只用于setter方法注入,不能提供如@Autowired多参数方法注入;
- @Resource在没有指定name属性的情况下首先将根据setter方法对于的字段名查找资源,如果找不到再根据类型查找;
- @Resource首先将从JNDI环境中查找资源,如果没找到默认再到Spring容器中查找,因此如果JNDI环境中有和Spring容器同名的资源时需要注意。
二、@PostConstruct和PreDestroy:通过注解指定初始化和销毁方法定义;
1、在测试类TestBean41中添加如下代码:
@PostConstruct public void init() { System.out.println("==========init"); } @PreDestroy public void destroy() { System.out.println("==========destroy"); }
2、修改测试方法如下:
@Test public void resourceInjectTest1() { ((ClassPathXmlApplicationContext) ctx).registerShutdownHook(); TestBean41 testBean41 = ctx.getBean("testBean41", TestBean41.class); Assert.assertEquals("hello", testBean41.getMessage()); }
类似于通过<bean>标签的init-method和destroy-method属性指定的初始化和销毁方法,但具有更高优先级,即注解方式的初始化和销毁方法将先执行。
12.2.4 JSR-330注解
在测试之前需要准备JSR-330注解所需要的jar包,到spring-framework-3.0.5.RELEASE-dependencies.zip中拷贝如下jar包到类路径:
com.springsource.javax.inject-1.0.0.jar |
一、@Inject:等价于默认的@Autowired,只是没有required属性;
二、@Named:指定Bean名字,对应于Spring自带@Qualifier中的缺省的根据Bean名字注入情况;
三、@Qualifier:只对应于Spring自带@Qualifier中的扩展@Qualifier限定描述符注解,即只能扩展使用,没有value属性。
1、首先扩展@Qualifier限定描述符注解来表示Mysql数据源
package cn.javass.spring.chapter12.qualifier; //省略部分import import javax.inject.Qualifier; @Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface JSR330Mysql { }
2、准备测试Bean:
package cn.javass.spring.chapter12; import javax.inject.Inject; import javax.inject.Named; import javax.sql.DataSource; import cn.javass.spring.chapter12.qualifier.JSR330Mysql; public class TestBean51 { private DataSource mysqlDataSource; private DataSource oracleDataSource; @Inject public void initDataSoruce( @JSR330Mysql DataSource mysqlDataSource, @Named("oracleDataSource") DataSource oracleDataSource) { this.mysqlDataSource = mysqlDataSource; this.oracleDataSource = oracleDataSource; } //省略getter }
3、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<bean id="testBean51" class="cn.javass.spring.chapter12.TestBean51"/>
4、在Spring修改定义的mysqlDataSourceBean数据源:
<bean id="mysqlDataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <qualifier value="mysqlDataSource"/> <qualifier type="cn.javass.spring.chapter12.qualifier.Mysql"/> <qualifier type="cn.javass.spring.chapter12.qualifier.DataSourceType"> <attribute key="ip" value="localhost"/> <attribute key="database" value="MYSQL"/> </qualifier> <qualifier type="cn.javass.spring.chapter12.qualifier.JSR330Mysql"/> </bean>
5、测试方法如下:
@Test public void testInject() { TestBean51 testBean51 = ctx.getBean("testBean51", TestBean51.class); Assert.assertEquals(ctx.getBean("mysqlDataSourceBean"), testBean51.getMysqlDataSource()); Assert.assertEquals(ctx.getBean("oracleDataSource"), testBean51.getOracleDataSource()); }
测试也通过了,说明JSR-330注解也能很好工作。
从测试中可以看出JSR-330注解和Spring自带注解依赖注入时主要有以下特点:
- Spring自带的@Autowired的缺省情况等价于JSR-330的@Inject注解;
- Spring自带的@Qualifier的缺省的根据Bean名字注入情况等价于JSR-330的@Named注解;
- Spring自带的@Qualifier的扩展@Qualifier限定描述符注解情况等价于JSR-330的@Qualifier注解。
12.2.5 JPA注解
用于注入EntityManagerFactory和EntityManager。
1、准备测试Bean:
package cn.javass.spring.chapter12; //省略import public class TestBean61 { @PersistenceContext(unitName = "entityManagerFactory") private EntityManager entityManager; @PersistenceUnit(unitName = "entityManagerFactory") private EntityManagerFactory entityManagerFactory; public EntityManager getEntityManager() { return entityManager; } public EntityManagerFactory getEntityManagerFactory() { return entityManagerFactory; } }
2、在Spring配置文件(chapter12/dependecyInjectWithAnnotation.xml)添加如下Bean配置:
<import resource="classpath:chapter7/applicationContext-resources.xml"/> <import resource="classpath:chapter8/applicationContext-jpa.xml"/> <bean id="testBean61" class="cn.javass.spring.chapter12.TestBean61"/>
此处需要引用第七章和八章的配置文件,细节内容请参考七八两章。
3、测试方法如下:
@Test public void testJpaInject() { TestBean61 testBean61 = ctx.getBean("testBean61", TestBean61.class); Assert.assertNotNull(testBean61.getEntityManager()); Assert.assertNotNull(testBean61.getEntityManagerFactory()); }
测试也通过了,说明JPA注解也能很好工作。
JPA注解类似于@Resource注解同样是先根据unitName属性去JNDI环境中查找,如果没找到在到Spring容器中查找。
原创内容,转载请注明私塾在线【http://sishuok.com/forum/blogPost/list/0/2545.html】
评论
一、@Resource:自动装配,默认根据类型装配,如果指定name属性将根据名字装配,可以使用如下方式来指定:
这一段写错了貌似,@Resource默认是先按名称找,找不到再byType
是的。
package cn.javass.spring.chapter12; import org.springframework.beans.factory.annotation.Autowired; public class TestBean12 { @Autowired //字段注入 private String message; [color=red]//省略getter和setter [/color] }
经调试,字段注入的方式,如果遇到private类型的字段,会在底层修改该字段的写入属性
java.lang.reflect.Field.setAccessible(true);,从而直接调用
java.lang.reflect.Field.set(bean, value);,而不需要调用setter方法的
位置:
二、@Autowired:自动装配
(1)、构造器注入:
在这个段落里 bean的配置是这样的
<bean id="testBean11" class="cn.javass.spring.chapter12.TestBean11"/>
在TestBean11这个类里面并没有使用无参的构造方法而只是这样的一个构造方法
@Autowired //构造器注入
private TestBean11(String message) {
this.message = message;
}
我记得网上有人解释@autowired是这样解释的,@autowired是bytype来进行注入的,spring首先获得类型这里我想应该是TestBean11吧,那么spring会去spring容器里面寻找有没有该类型的对象。可是该bean并没有一个无参的构造方法,也就无法实例化对象啊,那应该就找不到这样的对象啊,为什么这里却能成功呢?望博主指教,谢谢
@Autowired //构造器注入
private TestBean11(String message) {
会进行构造器注入啊 所以如果找到String类型的Bean 就能注入成功
LZ 他的意思是问你为什么没有无参数构造方法,还能得到实例化对象的。他可能还没理解spring的DI原理还有bean的生命周期
构造器注入嘛 你在构造器上加了@Autowire就相当于告诉spring我要构造器注入
请参考本章的
1)、构造器注入:通过将@Autowired注解放在构造器上来完成构造器注入,默认构造器参数通过类型自动装配,如下所示:
明白了,多谢博主和另外一位好心人啊!(*^__^*) 嘻嘻!
位置:
二、@Autowired:自动装配
(1)、构造器注入:
在这个段落里 bean的配置是这样的
<bean id="testBean11" class="cn.javass.spring.chapter12.TestBean11"/>
在TestBean11这个类里面并没有使用无参的构造方法而只是这样的一个构造方法
@Autowired //构造器注入
private TestBean11(String message) {
this.message = message;
}
我记得网上有人解释@autowired是这样解释的,@autowired是bytype来进行注入的,spring首先获得类型这里我想应该是TestBean11吧,那么spring会去spring容器里面寻找有没有该类型的对象。可是该bean并没有一个无参的构造方法,也就无法实例化对象啊,那应该就找不到这样的对象啊,为什么这里却能成功呢?望博主指教,谢谢
@Autowired //构造器注入
private TestBean11(String message) {
会进行构造器注入啊 所以如果找到String类型的Bean 就能注入成功
LZ 他的意思是问你为什么没有无参数构造方法,还能得到实例化对象的。他可能还没理解spring的DI原理还有bean的生命周期
构造器注入嘛 你在构造器上加了@Autowire就相当于告诉spring我要构造器注入
请参考本章的
1)、构造器注入:通过将@Autowired注解放在构造器上来完成构造器注入,默认构造器参数通过类型自动装配,如下所示:
位置:
二、@Autowired:自动装配
(1)、构造器注入:
在这个段落里 bean的配置是这样的
<bean id="testBean11" class="cn.javass.spring.chapter12.TestBean11"/>
在TestBean11这个类里面并没有使用无参的构造方法而只是这样的一个构造方法
@Autowired //构造器注入
private TestBean11(String message) {
this.message = message;
}
我记得网上有人解释@autowired是这样解释的,@autowired是bytype来进行注入的,spring首先获得类型这里我想应该是TestBean11吧,那么spring会去spring容器里面寻找有没有该类型的对象。可是该bean并没有一个无参的构造方法,也就无法实例化对象啊,那应该就找不到这样的对象啊,为什么这里却能成功呢?望博主指教,谢谢
@Autowired //构造器注入
private TestBean11(String message) {
会进行构造器注入啊 所以如果找到String类型的Bean 就能注入成功
LZ 他的意思是问你为什么没有无参数构造方法,还能得到实例化对象的。他可能还没理解spring的DI原理还有bean的生命周期
位置:
二、@Autowired:自动装配
(1)、构造器注入:
在这个段落里 bean的配置是这样的
<bean id="testBean11" class="cn.javass.spring.chapter12.TestBean11"/>
在TestBean11这个类里面并没有使用无参的构造方法而只是这样的一个构造方法
@Autowired //构造器注入
private TestBean11(String message) {
this.message = message;
}
我记得网上有人解释@autowired是这样解释的,@autowired是bytype来进行注入的,spring首先获得类型这里我想应该是TestBean11吧,那么spring会去spring容器里面寻找有没有该类型的对象。可是该bean并没有一个无参的构造方法,也就无法实例化对象啊,那应该就找不到这样的对象啊,为什么这里却能成功呢?望博主指教,谢谢
@Autowired //构造器注入
private TestBean11(String message) {
会进行构造器注入啊 所以如果找到String类型的Bean 就能注入成功
位置:
二、@Autowired:自动装配
(1)、构造器注入:
在这个段落里 bean的配置是这样的
<bean id="testBean11" class="cn.javass.spring.chapter12.TestBean11"/>
在TestBean11这个类里面并没有使用无参的构造方法而只是这样的一个构造方法
@Autowired //构造器注入
private TestBean11(String message) {
this.message = message;
}
我记得网上有人解释@autowired是这样解释的,@autowired是bytype来进行注入的,spring首先获得类型这里我想应该是TestBean11吧,那么spring会去spring容器里面寻找有没有该类型的对象。可是该bean并没有一个无参的构造方法,也就无法实例化对象啊,那应该就找不到这样的对象啊,为什么这里却能成功呢?望博主指教,谢谢
@Required只是表示必须的,@Autowire用于注入 可以完成构造器注入的
谢谢啊
比如
<bean id="baseiBatisDAO" abstract="true" ***></bean>
<bean id="applicationDao" class="*.dao.ApplicationDao" parent="baseiBatisDAO" />
现改成
<bean id="baseiBatisDAO" abstract="true" ***></bean>
@Repository("applicationDao") 这个parent该怎么写?
谢谢
xml方式是继承配置可以用你说的
而注解方式不用 继承子类后(自动会扫描子类中的如@Autowired注解 进行注入)
比如
<bean id="baseiBatisDAO" abstract="true" ***></bean>
<bean id="applicationDao" class="*.dao.ApplicationDao" parent="baseiBatisDAO" />
现改成
<bean id="baseiBatisDAO" abstract="true" ***></bean>
@Repository("applicationDao") 这个parent该怎么写?
谢谢
一、@Resource:自动装配,默认根据类型装配,如果指定name属性将根据名字装配,可以使用如下方式来指定:
这一段写错了貌似,@Resource默认是先按名称找,找不到再byType









发表评论
-
第十九章 动态URL权限控制——《跟我学Shiro》
2014-03-28 22:51 0用过Spring Security的朋友应该比较熟悉对URL ... -
第十九章 动态URL权限控制——《跟我学Shiro》
2014-03-28 22:51 0用过Spring Security的朋友应该比较熟悉对URL ... -
在应用层通过spring解决数据库读写分离
2012-11-09 07:28 3如何配置mysql数据库的主从? 单机配置mys ... -
跟我学spring3系列 word原版 下载
2012-11-03 20:39 122376《跟我学spring3系列》自发布以来得到大家的认可,非 ... -
跟我学spring3 电子书下载(完)
2012-05-03 14:23 52858感谢iteye各位网友对我的支持,在此谢过了! ... -
跟我学spring3 目录贴及电子书下载
2012-04-10 19:00 391204扫一扫,关注我的公众号 购买地址 ... -
【第十三章】 测试 之 13.3 集成测试 ——跟我学spring3
2012-03-30 07:11 2761013.3 集成测试 13.3.1 ... -
【第十三章】 测试 之 13.1 概述 13.2 单元测试 ——跟我学spring3
2012-03-28 07:46 2371513.1 概述 13.1.1 测 ... -
【第十二章】零配置 之 12.5 综合示例-积分商城 ——跟我学spring3
2012-03-27 15:13 2089912.5 综合示例 12.5.1 概述 在第十一 ... -
【第十二章】零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring3
2012-03-26 08:26 3000612.4 基于Java类定义Bean配置元数据 12 ... -
【第十二章】零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring3
2012-03-26 08:00 56712.4 基于Java类定义Bean配置元数据 12 ... -
spring培训PPT(欢迎下载)
2012-03-24 21:55 45java私塾的 spring培训的PPT 欢迎大家下载。 包括 ... -
java私塾的spring培训PPT(欢迎下载)
2012-03-22 12:41 2973java私塾的 spring培训的PPT 欢迎大家下载。 ... -
【第十二章】零配置 之 12.3 注解实现Bean定义 ——跟我学spring3
2012-03-22 08:00 2677512.3 注解实现Bean定 ... -
【第十二章】零配置 之 12.1 概述 ——跟我学spring3
2012-03-19 07:59 2040512.1 概述 12.1.1 什 ... -
【第十一章】 SSH集成开发积分商城 之 11.3 实现积分商城层 ——跟我学spring3
2012-03-16 08:09 1817611.3 实现积分商城层 11.3.1 概述 ... -
【第十一章】 SSH集成开发积分商城 之 11.2 实现通用层 ——跟我学spring3
2012-03-14 08:08 1921911.2 实现通用层 11.2 ... -
【第十一章】 SSH集成开发积分商城 之 11.1 概述 ——跟我学spring3
2012-03-13 16:37 1952411.1 概述 11.1.1 功能概述 ... -
【第十章】集成其它Web框架 之 10.4 集成JSF ——跟我学spring3
2012-03-13 08:46 12690先进行通用配置, 【第十章】集成其它Web框架 之 1 ... -
【第十章】集成其它Web框架 之 10.3 集成Struts2.x ——跟我学spring3
2012-03-12 08:16 13034先进行通用配置, 【第十章】集成其它Web框架 之 1 ...
相关推荐
12.1节概述零配置,12.2节和12.3节分别介绍注解实现Bean依赖注入和注解实现Bean定义。 在学习Spring的过程中,读者会从基础到高级,逐步掌握Spring框架的各个方面,最终能够熟练地应用Spring进行企业级应用的开发。...
总的来说,《跟我学Spring3》涵盖了Spring在ORM支持、事务管理、Web框架集成、SSH集成开发以及零配置和测试等多个方面的知识,是一本深入浅出的学习Spring的宝贵资料。通过这些章节,读者可以全面了解Spring的核心...
《跟我学Spring3》这本书详细...《跟我学Spring3》全面讲解了Spring如何与ORM框架、Web框架集成,以及如何实现事务管理和零配置开发。通过案例实践,读者可以深入理解Spring在实际项目中的应用,提升Java EE开发技能。
《跟我学Spring3》这本书是针对Spring框架的深入学习指南,涵盖了多个关键章节,包括Spring对ORM(对象关系映射)的支持、事务管理和与其他Web框架的集成等内容。以下是各章节主要内容的详细阐述: 1. **第八章:对...
《跟我学Spring3》是一本全面介绍Spring框架的教程,主要涵盖了Spring对ORM支持、事务管理以及与其他Web框架的集成等内容。以下是对其中关键知识点的详细解析: 1. **Spring对ORM的支持**: - **8.1 概述**:这...
#### 12.2 注解实现 Bean 依赖注入 - **依赖注入**:Spring 通过依赖注入机制实现了组件之间的解耦。通过注解(如 @Autowired、@Resource 等)可以简化依赖的声明和注入过程。 #### 12.3 注解实现 Bean 定义 - **...
《跟我学Spring3》是一本全面介绍Spring框架的教程,主要涵盖了Spring对ORM支持、事务管理、Web框架集成以及SSH集成开发等多个方面。Spring作为Java领域最流行的应用框架之一,其强大的功能和灵活性使得它在企业级...
《跟我学Spring3》是一本详细讲解Spring 3.0框架的教程,涵盖了Spring对ORM支持、事务管理、Web框架集成以及SSH集成等多个方面。以下是其中一些核心知识点的详细解析: 1. **Spring对ORM的支持**: - **8.1 概述**...