前言
上一篇的依赖注入是在配置文件中进行手工注入,今天再来学习一下基于注解的装配。
注解方式
在java代码中通过@Autowired或@Resource注解方式进行配置,但我们需要在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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
</beans>
@Autowired
- 使用注解方式对bean进行装配,通过匹配数据类型进行装配,该注解可以在类的成员变量,方法或者构造函数上进行注解,常用于对类的成员变量进行注解。
- 按照类型来装配bean
- 消除了java中的getter/setter方法
- 消除xml配置文件中对于bean的属性的配置
- 如果容器找不到注解的bean实例,会抛出异常,可以使用@Qualifier("name")来指定装配bean的name,如果容器中没有name相符的bean,则按照id匹配。
@Resource注解
用法:@Resource(name="xxx",type=xxx.class)
- 按照名称装配
- 如果同时指定了name和type属性,则会从容器中寻找name和type相匹配的唯一的bean进行装配,如果找不到,则抛出异常。
- 如果只指定name,则寻找name相匹配的,如果没有,则按照id值寻找,找到匹配的bean进行装配。
- 如果只指定了type,则按类型进行装配,如果找到一个则进行装配,如果没找到或找到多个,则抛出异常。
- 如果即没有指定name也没有指定type,则默认按照nam匹配,如果name都不匹配,则按照类型来装配。
实例
UserDao
package cn.sdut.dao;
public class UserDao {
public void saveUser() {
System.out.println("User is saved");
}
}
UserService
package cn.sdut.service;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import cn.sdut.dao.UserDao;
public class UserService {
@Autowired //从容器中装配userDao
private UserDao userDao;
public void print() {
userDao.saveUser();
}
}
Test
package cn.sdut.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.sdut.service.UserService;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService");
userService.print();
}
}
运行结果
没有报空指针,装配成功,@Resource注解效果一样。
虽然不需要我们配置属性了,但还是需要我们在xml中配置bean,依然很繁琐,因此引出了包的自动扫描
包的自动扫描
beans.xml中将配置的bean删除,加入包的自动扫描
<!-- 支持注解配置 -->
<context:annotation-config></context:annotation-config>
<!--包的自动扫描-->
<context:component-scan base-package="cn.sdut"></context:component-scan>
base-package就是你要扫描的包下,也就是cn.sdut开头的所有包。
需要配合下面几个注解使用
- @Repository //dao层注解
- @Service //逻辑层注解
- @Controller //控制层注解
- @Component //其他注解,不属于以上各层或不好区分时,使用此注解
还是上次的实例
UserDao
package cn.sdut.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
public void saveUser() {
System.out.println("User is saved");
}
}
UserService
package cn.sdut.service;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.sdut.dao.UserDao;
@Service
public class UserService {
@Autowired //从容器中装配userDao
private UserDao userDao;
public void print() {
userDao.saveUser();
}
}
运行结果不变。
总结:从手工配置bean,配置bean的属性->到使用注解、自动扫包,果然懒惰才是第一生产力啊,古人诚不欺我。