尚学堂Spring视频教程(四):使用Annotation
之前我们的bean都配置在XML里,并且通过bean的property标签来指定依赖关系,如果项目很大,那岂不是要配置很多这样的property标签?Spring提供了注解的方式来解决这个问题
@Autowired
在需要注入的bean的setter方法上加这个注解,就不需要指定property标签了,因为Spring会通过byType的方式去寻找对应类型的bean自动的注入,如果找到了多个同类型的bean,就会报异常

package com.bjsxt.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; public class UserService { private UserDAO userDAO; public void init() {
System.out.println("init");
} public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
} @Autowired
public void setUserDAO( UserDAO userDAO) {
this.userDAO = userDAO;
} public void destroy() {
System.out.println("destroy");
}
}
加上@AutoWired注解的UserService
package com.bjsxt.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.bjsxt.model.User; //Dependency Injection
//Inverse of Control
public class UserServiceTest { @Test
public void testAdd() throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); UserService service = (UserService)ctx.getBean("userService");
service.add(new User()); ctx.destroy(); } }
单元测试
运行,会报错,因为发现了u和u2两个可以注入的bean,去掉一个,运行成功
@Qualifier
针对上面的问题,我们可以使用@Qualifier注解,这个注解是通过byName的方式,也就是可以指定id,这个注解需要加在setter方法的参数的最前面,有一个参数表示依赖的bean的id
package com.bjsxt.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; public class UserService { private UserDAO userDAO; public void init() {
System.out.println("init");
} public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
} public void setUserDAO(@Qualifier("u") UserDAO userDAO) {
this.userDAO = userDAO;
} public void destroy() {
System.out.println("destroy");
}
}
加上@Qualifier注解的UserService
这样运行就不会报错了,因为会直接找到id为u的bean注入到UserService的userDAO属性
@Resource
这个注解遵循JSR-250标准,属于J2EE的注解,所以引入新的包“common-annotation.jar”。同样在setter方法上使用该注解,其他部分同上。注意该注解默认使用的是byName的方式,如果没有指定该注解的name属性值,会默认的寻找以setter方法参数的名称为id的bean,例如本例中setter方法的参数名是“userDAO”,就会在配置文件中寻找id为“userDAO”的bean,如果没有找到,就按照byType的方式,如果又发现了两个符合类型的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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl">
</bean>
<bean id="u2" class="com.bjsxt.dao.impl.UserDAOImpl">
</bean> <bean id="userService" class="com.bjsxt.service.UserService" > </bean> </beans>
配置文件
package com.bjsxt.service;
import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; public class UserService { private UserDAO userDAO; public void init() {
System.out.println("init");
} public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
} @Resource
public void setUserDAO( UserDAO userDAO) {
this.userDAO = userDAO;
} public void destroy() {
System.out.println("destroy");
}
}
使用@Resource注解的UserService
package com.bjsxt.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.bjsxt.model.User; //Dependency Injection
//Inverse of Control
public class UserServiceTest { @Test
public void testAdd() throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); UserService service = (UserService)ctx.getBean("userService");
service.add(new User()); ctx.destroy(); } }
单元测试

看到了吧,默认按照byName,本来想找id为“userDAO”的bean,结果配置文件中没有,就转为按照byType的方式,结果找到了两个符合类型的bean,id分别为"u"和“u2”。解决办法是给注解加上name="u"来指定一个想要的bean,或者不加name属性,直接在配置文件中指定一个id为"userDAO"bean
@Component
上面的一些注解尽管已经很方便了,但是配置文件里还是要写很多需要被用来注入的bean标签,有没有办法可以让我们连bean标签都不用写呢,答案是肯定的,使用@Component注解就可以做到,我们首先需要在配置文件中加上一句<context:component-scan base-package="com.bjsxt"/>,这句代码的意思就是说:配置文件里面的bean都不用写了,你直接去com.bjsxt下面所有的包里面去扫描加了@componet注解的类作为需要的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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="com.bjsxt"/> <bean id="userService" class="com.bjsxt.service.UserService" > </bean> </beans>
配置文件
已经不用写被用来注入的bean标签了,在setter方法加了@Resource注解的基础上,我们需要在被用来注入的类上加上@Component注解
package com.bjsxt.dao.impl; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; @Component("u")
public class UserDAOImpl implements UserDAO { public void save(User user) {
//Hibernate
//JDBC
//XML
//NetWork
System.out.println("user saved!");
} }
UserDAO的实现类UserDAOImpl
package com.bjsxt.service;
import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; /*@Component("userService")*/
public class UserService { private UserDAO userDAO; public void init() {
System.out.println("init");
} public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
} @Resource(name="u")
public void setUserDAO( UserDAO userDAO) {
this.userDAO = userDAO;
} public void destroy() {
System.out.println("destroy");
}
}
UserService
package com.bjsxt.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.bjsxt.model.User; //Dependency Injection
//Inverse of Control
public class UserServiceTest { @Test
public void testAdd() throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); UserService service = (UserService)ctx.getBean("userService");
service.add(new User()); ctx.destroy(); } }
单元测试
@Resource和@Component都可以指定一个name来相互对应,这样就可以准确知道setter方法的参数具体需要那个被用来注入的类了
另外我们发现配置文件中还有一个名为“userService”的bean,因为测试代码中调用了getbean("userservice")这个方法,如果把bean标签去掉就找不到了,会报错,我们可以在该bean对应的类上加上@Component标签,并指定名称"userservice”,这样就可以直接把配置文件中的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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="com.bjsxt"/> </beans>
修改后的配置文件
package com.bjsxt.service;
import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; @Component("userService")
public class UserService { private UserDAO userDAO; public void init() {
System.out.println("init");
} public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
} @Resource(name="u")
public void setUserDAO( UserDAO userDAO) {
this.userDAO = userDAO;
} public void destroy() {
System.out.println("destroy");
}
}
加上@Component的UserService
项目组织如图:

注:在spring2.5中,@Component,@Repository,@Controller,@Service的作用是一样的,不过在后续版本中就不一定了
最后,再说三个注解
@Scope:参数可以指定为“singleton”或“prototype”,和之前讲的一样,指定bean的生存范围,直接加在类名上就可以了
@PostConstruct:代表之前bean中的init-method,加在方法上就可以了
@PreDestroy:代表之前bean中destroy-method,加在方法上就可以了
尚学堂Spring视频教程(四):使用Annotation的更多相关文章
- 尚学堂Spring视频教程(六):AOP Annotation
此处省略N个字.... 直接看下面 推荐链接: Spring Aop实例之AspectJ注解配置
- 尚学堂Spring视频教程(七):AOP XML
此处省略N个字.... 直接看下面 推荐链接: Spring Aop实例之xml配置
- 尚学堂Spring视频教程(五):Spring AOP
在第一节中,我们自己模拟了一个Spring,实现一个保存用户的操作,假如现在有一个需求,在保存的时候记录日志,该怎么做呢? 暂且将记录日志操作就简单的变为在保存用户前输出一句话“save start. ...
- 尚学堂Spring视频教程(三):Spring Core中的其他特性
集合装配 如果bean中有一些集合属性,配置文件的配置如下 package com.bjsxt.dao.impl; import java.util.List; import java.util. ...
- 尚学堂Spring视频教程(二):Spring控制反转
用Spring来实现IOC 在上节中我们自定义了一个接口BeanFactory和类ClassPathXmlApplicationContext来模拟Spring,其实它们在Spring中确实是存在的, ...
- 尚学堂Spring视频教程(一):模拟Spring
Spring简单的说就是作为控制反转的容器,看这篇文章前需要先搞懂“控制反转和依赖注入“这个设计模式 我们先来模拟Spring,实现用户添加的功能,新建WEB项目”Spring_0100_Abstra ...
- [JAVA教程] 2016年最新spring4框架搭建视频教程 【尚学堂】
Spring4框架 主讲:邹波 类型:SSH 适合对象:学习完javase.数据库技术.jdbc者 Spring4.0作为一个广泛使用的开源框架,它由Rod Johnson创建.它是为了解决企业应用开 ...
- 尚学堂 213_尚学堂_高淇_java300集最全视频教程_反射机制_提高反射效率_操作泛型_操作注解_合并文件.mp4
在反射的时候如果去掉了安全性检测机制,能够大大的提高反射的执行效率,我们来看下面的代码进行比较 package com.bjsxt.test; import java.lang.reflect.Met ...
- 尚学堂JAVA基础学习笔记
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
随机推荐
- JS实现HashMap
/** * ********* 操作实例 ************** * var map = new HashMap(); * map.put("key1","Valu ...
- Python通用序列操作
1.序列概览 1.数据结构 序列.容器 Python中最基本的数据结构是序列,其有索引(从左到右第一个索引为0,从右到左第一个索引为-1). Python包含6中内建的序列: 列表 元组 字符串 Un ...
- SSH(Struts,Spring,Hibernate)和SSM(SpringMVC,Spring,MyBatis)之间区别
http://m.blog.csdn.net/article/details?id=52795914#0-qzone-1-52202-d020d2d2a4e8d1a374a433f596ad1440
- SQL增删改语句常用
创建table: create table tab_name( col1 type; 约束:主键-外键-非空-检查-唯一 col2 type; ); 删除表 : drop table tab_name ...
- HTTP Code
所有 HTTP 状态代码及其定义. 代码 指示 2xx 成功 200 正常:请求已完成. 201 正常:紧接 POST 命令. 202 正常:已接受用于处理,但处理尚未完成. 20 ...
- quick sort 的简化实现
Pivot 随机选取意义不大 第一种方法使用随机pivot,使得尽可能平均二分序列,而实际上一般来说需要排序的集合往往是乱序的,无需重新生成随机数作为pivot,大可使用固定位置的数作为pivot,这 ...
- Java中的构造代码块
代码块 ----a静态代码块 ----b构造代码块 ----c普通代码块 执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. a.静态代码块: 静态代码块 ...
- GridView
1.设置间隔变色 css: .oddRow{ background:#fafafa; } js: ,loadComplete:function(){ $("tr.jqgrow:odd&quo ...
- .Net WebApi 实现OAuth2.0认证
现在多数公众平台提供的api都使用OAuth2.0认证模式,最近在搞Android方面的开发,身份认证和权限控制的各方面比较来说,使用OAuth认证的还是比较靠谱,OAuth2.0的协议可以参考htt ...
- Linux-Rsync服务器/客户端搭建实战
一.需求 每晚汇总各机器的操作日志,同步到主服务器进行日志分析. 二.基础知识 rsync 分为服务器端.客户端,服务器端搭建比客户端辛苦一些(也是很简单). rsync 服务器是指以 deamon ...