如果转载文章请注明出处, 谢谢 !
本系列文章是学习完 Spring4.3.8 后的详细整理, 如果有错误请向我指明, 我会及时更正~
Spring4.3.8
Spring4.3.8学习[一]
3.4 依赖注入(DI)
控制反转,我们可以把它看作是一个概念。而依赖注入(Dependency Injection)是控制反转的一种实现方法.
James Shore给出了依赖注入的定义:依赖注入就是将实例变量传入到一个对象中去(Dependency injection means giving an object its instance variables)。
3.4.1 xml 形式
3.4.1.1 使用构造器注入
通过参数顺序, 类型等
3.4.1.2 使用属性 setter 方法
public class Person {
private String name;
private int age;
private String gender;
private Car car;
private List list;
private Set set;
private Map map;
private Properties properties;
private Object[] objects;
[属性 setter 方法]
}
简单Bean的注入
引用其他Bean
3.4.1.3 装配 list 集合
3.4.1.4 装配 set
set1
3.4.1.5 装配 map
3.4.1.5 装配 properties
pp1
pp2
3.4.1.6 装配 Object[]
3.4.2 注解 Annotation
注解的注入会在XML之前,因此后者配置将会覆盖前者.
配置bean
3.4.2.1 @Component
@Component是所有受 Spring 管理组件的通用形式,泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Component 不推荐使用。
@Component
public class Person {
}
3.4.2.2@Controller
@Controller对应表现层的Bean,也就是Action, 例:
@Controller
@Scope("prototype")
public class UserAction {
}
3.4.2.3 @Respository
用于标注数据访问组件,即DAO组件
@Repository
public class UserDao {
}
3.4.2.4 @Service
用于标注业务层组件
@Service
public class UserServiceImpl {
}
对于扫描到的组件, Spring有默认的命名策略 :
1)使用非限定类名,第一个字母小写
(UserServiceImpl -> userServiceImpl)
2)在注解中通过 value 属性值标识组件的名称
(通常可以将UserServiceImpl -> userService,可以将Impl拿掉,这是一个习惯)
@Service("userService")
public class UserServiceImpl {
}
(3)当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明
:
base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.
当需要扫描多个包时, 可以使用逗号分隔.
配置 bean 的属性
3.4.2.5 @Autowired
使用@Autowired 注解自动装配, @Autowired 默认按类型装配.
可以在普通setter方法上使用@Autowired注解
public class UserServiceImpl implements UserService{
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
可以将注解应用到构造器和字段上
public class UserServiceImpl implements UserService{
private UserDao userDao;
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
}
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
}
可以将注解应用到任意名称或参数的方法上
public class UserServiceImpl implements UserService{
private UserCatalog userCatalog;
private UserDao userDao;
@Autowired
public void prepare(UserCatalog catalog, UserDao dao){
this.userCatalog = catalog;
this.userDao = dao;
}
可以把指定类型的所有Bean提供给一个数组类型, 集合类型的变量
public class UserServiceImpl implements UserService{
@Autowired
private UserCatalog[] catalogs;
}
xml 中只定义了几个 对应bean
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,一旦找不到对应的Bean,自动注入就会失败。若要改变默认的策略或允许null值,可以设置它required属性为false。
public class UserServiceImpl implements UserService{
// xml 中没有定义UserFinder的 bean
@Autowired(required = false)
private UserFinder userFinder;
}
3.4.2.6 @Qualifier
使用@Qualifier调整基于注解的自动注入.
在指定参数上使用@Qualifier,可以缩小类型匹配的范围,更容易为参数找到指定的Bean。
[想使用按名称装配,可以结合@Qualifier注解一起使用]
public class UserServiceImpl implements UserService{
@Qualifier("userD")
@Autowired
private UserDao userD;
}
对应的Bean定义如下所示。
标识值为“userDe”的Bean将会被标记为@Qualifier(“userDe”)的参数所注入:
如果全部使用注解, 可以在UserDaoImpl中使用Repository配置
@Repository("userDe")
public class UserDaoImpl implements UserDao{
}
3.4.2.7 @Resource
@Resource 注解和@Autowired一样,也可以标注在字段或属性的setter方法上.
@Resource注解默认按名称装配。
名称可以通过@Resource的name属性指定,如果没有指定name属性,
当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象;
当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
public class UserServiceImpl implements UserService{
@Qualifier("userD")
@Autowired
private UserDao userD;
@Resource(name = "daoU")
private UserDao userDao;
}
注: 如果没有指定name属性,并且按照默认的名称找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。
3.4.2.8 @Required
@Required注解应用于Bean属性的setter方法,如下:
public class UserServiceImpl implements UserService{
private UserDao userDao;
@Required
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
这个表明Bean的属性值必须在配置中指定,可以通过显示的在Bean定义中指定,也可以使用自动注入。若没有为这个属性指定值,那么容器会抛出一个异常。
3.4.2.8 @PostConstruct & @PreDestroy
生命周期注解
之前的做法是在xml中定义init-method 和 destroy-method方法
public class User {
public User() {
System.out.println("user .. 构造函数");
}
@PostConstruct
public void init(){
System.out.println("I'm init method using @PostConstrut....");
}
@PreDestroy
public void destroy(){
System.out.println("I'm destory method using @PreDestroy.....");
}
}
3.5 扫描
spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理.
它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:
- 引入context命名空间 需要在xml配置文件中配置以下信息
- 在配置文件中添加context:component-scan标签
在 base-package 指明一个包, 表明自动扫描目录 com.lanou 包及其子包中的注解,当需要扫描多个包时, 可以使用逗号分隔.
其他用法:
3.6 Spring 的继承
public class People {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Student extends People {
}
public void testExtents(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
// student 打印出来的名字为 null
System.out.println(student.getName());
}
配置文件需要更改
还有其他方式解决 student 的名字赋值问题么?
student 也继承了 people 的 name setter 方法
Spring4.3.8学习[三]
Spring4.3.8学习之 与 Struts2 整合[四]
Spring4.3.8学习之与Hibernate4 整合[五]
Spring4.3.8学习之S2SH 整合[六]