在上面四篇文章中大概分析了一下Bean的载入,其实这个过程就是在Ioc容器中创建BeanDefinition的数据映射。可是对于Bean的实例化并未涉及,在以前的分析中也提到,bean的实例化是在依赖注入是才具体完成。java
关于Spring,咱们最早想到的就两个Ioc和Aop;而后关于Ioc咱们又能牵扯出两个:控制反转和依赖注入。 控制反转和依赖注入在网上被无数大神亦或菜鸟解读过,这里就不罗列那些概念了,直接看:post
不使用Springspa
public class UserService {
//手动new一个
UserDao userDao = new UserDaoImpl();
public int insertUser(String userName) {
return userDao.insertUser(userName);
}
}
复制代码
使用Spring(以注解方式)设计
public class UserService {
@Autowired
private UserDao userDao;
public int insertUser(String userName) {
return userDao.insertUser(userName);
}
}
复制代码
看起来貌似没有啥很大的改变,区别呢?3d
咱们先来分析下在一个类中这两种申明的区别:代理
UserDao userDao;
code
userDao是UserDao类型的引用名称。仅仅是声明了一个变量引用名称。并无作实例化,userDao的实例化能够经过set方法进行设置(Spring中以前经常使用的就是set方法注入);当咱们初始化持有userDao的这个类时咱们还不知道userDao到底具体指向哪一个堆中的对象地址。cdn
UserDao userDao = new UserDaoImpl();
对象
而这个,申明一个变量名称,并将userDao直接指向new UserDaoImpl()建立的对象。blog
咱们来看Spring中关于注入以后对象地址以及不使用注入方式对象的地址:
一、直接注入
经过上面三幅图能够明显的看出,本身手动new的对象没有使用代理的方式,而托管给Spring注入的对象均是经过动态代理来完成的。
关于动态代理:《猪弟拱Java》连载番外篇:Java代理(中)
总结:当某个角色(多是一个Java实例,调用者)须要另外一个角色(另外一个Java实例,被调用者)的协助时,在未使用Spring来管理Bean的程序设计过程当中,一般由调用者来建立被调用者的实例。但在Spring里,建立被调用者的工做再也不由调用者来完成,所以称为控制反转;建立被调用者实例的工做一般由Spring容器来完成,而后注入调用者,所以也称为依赖注入。
那么如今要考虑问题就是,何时会触发咱们的依赖注入呢?Bean的实例化是否必须在依赖注入时才能完成呢?在Spring中又是经过哪些类来完成注入工做的呢?
一、何时会触发咱们的依赖注入
答:用户第一次向容器获取Bean的时候出发。
二、Bean的实例化是否必须在依赖注入时才能完成
这个其实不是必须的,我们都知道BeanDefinition中有lazy-init这样一个属性,咱们能够经过控制这个属性的设置来让容器完成对Bean的预实例化。预实例化就是说它的依赖注入是在实例化过程当中完成的。
第一和第二个问题将会在分析第三个问题的时候慢慢的细化分析。因此第三个问题其实没啥鸟用,但也是最最最核心的,就是为了引出后面关于一些具体类的分析的。