Spring创建对象的几种方式
简单对象的创建
- 可以通过构造方法 直接创建对象 —> spring底层通过反射方式
复杂创建对象
-
通过实现FactoryBean接口,实现里面三个方法
-
getObject —> 书写位置 ----> Spring工厂回调这个方法
-
如果Class中指定的类型 也就是spring配置文件中指定class属性,是FactoryBean接口的实现类,那么通过id值获得的是这个类所创建的复杂对象
-
public class MyFactoryBean implements FactoryBean { //实现了里面的方法, getObject() { // mysql驱动 } } // 在进行获取myFactoryBean id的时候获取的对象则是Connection对象,而不再是我们在配置文件中指定的对象了
-
<bean id="myFactoryBean" class="xxxx.MyFactoryBean"></bean>
-
细节
- 如果就需要获取FactoryBean类型的对象 则在获取的时候 ctx.getBean(“&id名称”)获取的就是MyFactoryBean这个对象
-
-
getObjectType
-
isSingleton
- 如果返回false 表示每次都会创建一个新的对象,返回true表示只创建一个
- 返回true 或者是false 如果这个对象能被大家共用则返回true(SqlSessionFactory),否则返回false(Connection)
-
-
静态工厂 自己定义一个类,编写一个静态方法,然后再Spring的配置文件 指定factory-methed属性 中写入这个方法的名称
// 当然这个类的名称可以直接随意写 public static Object getObject(){ // xxxxx }
<bean id="" class="xxx.类名" factory-methed="getObject"></bean>
-
实例工厂:自己定义一个类,编写一个方法,然后再Spring的配置文件 指定factory-bean属性和 factory-methed属性中写入这个方法的名称 实例方法不可能通过类名.方法名来创建 只能先通过创建对象,后再调用其方法
// 当然这个类的名称可以直接随意写 public Object getObject(){ // xxxxx }
<!--id 要于factory-methed保持一致 --> <bean id="myFactory" class="xxx.类名"></bean> <!--先创建一个对象--> <bean id="" factory-bean="myFactory" factory-methed="getObject"></bean> <!--后在创建复杂对象的同时指定工厂bean是谁,工厂中的方法是谁-->
Spring注入几种方式
Set注入
<bean id="xxx" class="xxxx.类名">
<property name="xxx" value="xxx"></property>
<property name="xxx" value="xxx"></property>
</bean>
构造器注入
<bean id="xxx" class="xxx.类名">
<constructor-arg name="id" value="2"></constructor-arg>
</bean>
自动注入(属性)(用的少后期都是基于注解)
<!--自动注入就不需要写property和constructor-arg标签了-->
<!--autowire属性 默认为no-->
<!--类中必须指定set方法-->
<bean id="xxx" class="xxx.类名" autowire=""></bean>
<!--如果在beans中添加属性为default-autowire表示在被beans标签包裹的bean标签都会进行自动注入-->
<beans default-autowire="xxx"></beans>
set注入的好处
- 不会发生重载,构造注入会产生重载,一旦重载就会把简单的问题复杂化
- spring内部在注入的时候,他大量的编码是产生注入的过程也是使用的set注入
- set注入可以避免循环引用
set注入的两种形式 用户在前,容器在后
- 程序员完成注入
- 八种基本类型的注入,使用value,或者list,map标签
- 自建类注入,使用ref-bean完成 简写ref
- 容器(spring)自己的注入 Aware 知道
- Aware接口 都实现了set方法
- 衍生接口
- BeanNameAware :当我们的对象实现BeanNameAware之后,可以获得我当前实现了BeanNameAware这个接口的对象他当前在工厂中的ID (beanName)
- BeanFactoryAware:当我们的对象实现了BeanFactoryAware之后,可以获得当前对象的工厂对象
- Aware接口 都实现了set方法
scope=“prototype” 在注入过程中失效的问题
public interface UserDAO {
public void save();
}
public class UserDAOImpl implements UserDAO{
@Override
public void save() {
System.out.println("UserDAOImpl.save");
}
}
public interface UserService {
public void register();
}
package com.dongdong.source.bean;
public class UserServiceImpl implements UserService{
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
private UserDAO userDAO;
@Override
public void register() {
System.out.println("userDAO="+userDAO);
userDAO.save();
}
}
<bean id="userDAO" class="com.dongdong.source.bean.UserDAOImpl" scope="prototype"></bean>
<bean id="userService" class="com.dongdong.source.bean.UserServiceImpl">
<property name="userDAO" ref="userDAO"></property>
</bean>
<!--这里的失效是加“” 因为我们每次去获取userService的时候是去从单例池中获取的此时单例池里面已经有userDao,只调用了一次,如果想解决这个问题可以让该类是实现BeanFactoryAware里面的方法,在方面里面getBean("userDAO")-->
编写测试类
@Test
public void test3(){
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring.xml"));
UserService userService = (UserService) beanFactory.getBean("userService");
UserService userService1 = (UserService) beanFactory.getBean("userService");
userService.register();
userService1.register();
}
//输出
userDAO=com.dongdong.source.bean.UserDAOImpl@49993335
UserDAOImpl.save
userDAO=com.dongdong.source.bean.UserDAOImpl@49993335
UserDAOImpl.save
// 获取两个bean结果两个bean的地址都一样
Spring初始化几种
- 方法配置初始化:在实体类中定义一个方法,后在配置文件中定义 init-method属性指定该方法的名称
// 初始化方法 --> spring容器(工厂)
public void myInit(){
// 可能需要io操作的话
System.out.println("User.myInit");
}
<bean id="u" class="com.dongdong.source.bean.User" scope="prototype" init-method="myInit"></bean>
- 接口初始化:实现InitializingBean这个接口,实现里面的一个方法afterPropertiesSet
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("User.afterPropertiesSet");
}
// 如果两个同时有,则接口的那个先被执行
到此一个实例对象就算创建完成
Spring销毁几种
- 方法配置销毁:在实体类中定义一个方法,后在配置文件中定义 destroy-method 属性指定该方法的名称
// 销毁方法
// 对象真正销毁之前做一些释放资源的操作 如 io操作 流的关闭 io.close()
public void myDestory(){
System.out.println("User.myDestory");
}
<bean id="u" class="com.dongdong.source.bean.User" scope="prototype" init-method="myInit" destroy-method="myDestory"></bean>
- 接口销毁:实现DisposableBean这个接口,实现里面的一个方法destroy
@Override
public void destroy() throws Exception {
System.out.println("User.destroy");
}
创建对象 -----> 注入(set)给属性赋值 分为容器注入和用户注入 ----> 对象交给BeanPostProcessor对象加工 ---->加工后的对象 ----> 初始化 ----> 容器注入(Aware) ---- 接口初始化和方法配置初始化 ----> 实例对象 ----> 加工初始化后的对象 再次交给BeanPostProcessor----> BeanPostProcessor返回 最终的加工的对象就可以交给调用者使用了 -----> 对象的销毁(工厂销毁)---->接口销毁和方法配置销毁
BeanPostProcessor好处
- 减少加工代码的冗余:工厂不可能只创建一个对象,肯定是n个对象的创建,如果要一个个给对象添加功能那就太麻烦了,所以BeanPostProcessor就把需要加工的对象统一来进行处理,减少代码冗余
- 解掉加工代码的耦合:作为我加工来讲,加工的功能一定不是主要的功能,次要的功能可有可无,如果我把这些功能写在创建对象的代码中,日后改起来麻烦,加工的话想加就加,不会影响到我现有的代码,从而实现解耦合
BeanPostProcessor两个方法对应的Spring初始化前和初始化后
- postProcessBeforeInitialization(Object bean, String beanName) 返回值为Object类型
- 注入完成后的到一个bean通过Object bean把bean传进来进行初始化前的加工通过返回值交给工厂进行初始化bean操作
- postProcessAfterInitialization(Object bean, String beanName) 返回值为Object类型
- 初始化完成的bean通过Object bean又传进来进行初始化后的加工最终得到一个完整的bean交给掉用着使用
属性填充中的BeanPostProcessor 和初始化过程中的BeanPostProcessor的区别
- 属性填充:一般情况下 指的都是Spring自己提供的
- 初始化过程中:一般是程序员提供的BeanPostProcessor
Spring Aop动态代理的创建
- 基于BeanPostProcessor 创建,在初始化的时候创建,在applyBeanPostProcessorsAfterInitialization这个方法中也就是在初始化后创建的代理对象 代理对象
Spring创建Bean的源码分析
1、先走getBean()这个方法,会走到doGetBean()这个方法
protected <T> T doGetBean(
// name 就是我们的getBean的时候的id值,requiredType我们对最终创建对象类型的一个预期
// 比如说User user = beanFactory.getBean("u",User.class);
// 我们这次创建的是啥类型,就是通过requiredType来知道,显然我们需要创建User.class这种类型,
// 创建这种类型的好处就我们不需要在获取这个对象的时候在进行强制类型转换了
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 传进来的name其实就是beanName 比如你传入一个u beanName就是u 但是 如果你在配置文件指定了别名
// 传入的是别名,但是beanName还是你在配置文件写的id值 总的一句话就是说 name并不一定就是id,可能是别名,但是beanName一定是id
// transformedBeanName就是去获取bean的id值
// 如果getBean(name) ---> id
// 如果getBean(&id) ---> id
// name值 等于 getBean(name)
// beanName 必须等于 id值
// 保证全局唯一
String beanName = transformedBeanName(name);
// 最终我返回的创建好的对象
Object bean;
// 从这个单例池中去获取Spring曾经创建或的对象的
//beanName(一定是我们在配置文件指定的id值)的过程 单例池的名称是一个map类型
// this.singletonObjects private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 网上也有人说这个就是spring的一级缓存
// 创建bean的实例分为是否是singleton类型(单例类型) 是否是prototype类型(原型类型)是否为其他作用域(比如在web环境下request,session)类型
// 就我们在xml配置文件中指定scope为singleton或者prototype还有其他
Object sharedInstance = getSingleton(beanName);
// spring在创建对象 对象两种状态:
// 完全状态:对象创建 属性填充 初始化 (代理AOP)
// 正在创建中:仅仅有一个简单的对象
// 获取的这个对象不为空,说明之前就已经被创建好了
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 该对象是不是正在被创建中
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 如果是简单对象,则直接返回bean
// 如果是FactoryBean对象 返回FactoryBean#getObject返回值
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 缓存池里面没有,再获取对象 40 到 148
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 校验
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 56~75 父子容器概念
// 获取父容器
BeanFactory parentBeanFactory = getParentBeanFactory();
// containsBeanDefinition(beanName)表达的意思为子容器没有这个id所对应的配置去父容器里面找
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取父容器
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 递归调用doGetBean 如果有父容器且这个配置在子容器中没有,那么实例化父容器对应的bean
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 上面都是查到对象的过程,如果单例池有则怎么样,如果没有则去父容器查找,父容器没有则自己创建
// typeCheckOnly 这个值其实是doGetBean方法中的一个参数,默认就是false
// 如果为false spring会帮我们创建对象 或者获得这个对象 返回调用者
// 比如 beanFactory.getBean("u",User.class)
// 如果我把typeCheckOnly设置成true spring是不会帮我们创建对象判断当前工厂获取的类型是不是User类型
if (!typeCheckOnly) {
// 我们要把这个bean标记 是真的需要创建对象,而不是做类型的检查
// 1、标记这个bean被创建,如果我这个bean正在被创建中,就意味着已经被合并过了
// 就应该从clearMergedBeanDefinition 里面清空 含义就是如果我创建他,他就应该是一个已经被创建好了的bean
markBeanAsCreated(beanName);
}
try {
// 如果需要搞清楚markBeanAsCreated 就需要进入到这个方法
// 把父和子的配置整合到一起
// 为啥要合并,解决父子bean的问题
/*
<!--如果一个bean中,出现了abstract=true这个属性,说明他就一个专门被继承的一个抽象bean,也称之为父bean-->
<bean id="p" abstract="true">
<property name="id" value="10"/>
<property name="ids" value="20"/>
</bean>
<!--子bean 把共有的东西抽取到父bean,是为了减少子bean的配置信息-->
<bean id="p1" class="com.dongdong.source.bean.User" parent="p">
<property name="id" value="10"/>
<property name="password" value="20"/>
</bean>
*/
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 校验 如果两个bean都abstract=true 这个标签,可能抛出该异常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
/**
* 比如说我Service 需要依赖于DAO 一般我们这样写
* <bean id="userDAO" class="com.dongdong.source.bean.UserDAOImpl" ></bean>
* <bean id="userService" class="com.dongdong.source.bean.UserServiceImpl">
* <property name="userDAO" ref="userDAO"></property>
* </bean>
* 不过可以再 bean 标签中添加 depends-on 基本不用
* <bean id="userService" class="com.dongdong.source.bean.UserServiceImpl " depends-on="userDAO">
*/
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//真正的对象创建
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 打一个标识,标志这个对象正在创建中 标记在isPrototypeCurrentlyInCreation会触发,判断他是否正在被创建,如果发现你正在被创建则抛出异常
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 清除一些标记位
afterPrototypeCreation(beanName);
}
// 如果是普通对象则直接返回,如果是FactoryBean则调用geObject进行返回
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; consider " +"defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex);
}
}
1、获取对象的过程
1、进入到getSingleton这个方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 第一次从这个map中获取对象 一级缓存 他先被调用
Object singletonObject = this.singletonObjects.get(beanName);
// 如果获取的对象为null
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 第二次获取 预先单例池 二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果获取还是为null
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
// 再进行获取 单例工厂池 三级缓存
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
// 为什么需要设计这么庞大的循环体系呢?循环引用 我中有你你中有我
// 何为循环引用
public class A {
private B b; // A类里面存储了一个b类的引用
setB(b);
}
public class B {
private A a; // B类里面存储了一个a类的引用
setA(a)
}
// 我创建A 我需要注入B 而我注入B就必须要创建B的实例 创建B的实例的时候,我需要注入A,而我注入A就必须要创建A的实例
// 这就形成了一个环
// 解决循环引用的问题就是依托于三级缓存
2、进入到getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 判断这个name(id) 所对应的类,是不是个FactoryBean 能进来说明你name是以&开头的
if (BeanFactoryUtils.isFactoryDereference(name)) {
// beanInstance是个null类型的bean直接返回beanInstance
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// beanInstance不是FactoryBean类型则抛异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 两个满足一个就直接返回这个bean的实例
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 调用getObject()方法
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
3、进入到markBeanAsCreated 方法
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
// 清空被合并bean的信息
clearMergedBeanDefinition(beanName);
// 标记这个bean需要被创建
this.alreadyCreated.add(beanName);
}
}
}
}
4、进入到getMergedLocalBeanDefinition方法
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
// 最终获得的产品 先存放一个引用
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
// 如果getParentName为null ,就是我们再子容器里面设置parent这个属性为空,则说明没有父容器
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
// 直接new合并完成的bean
mbd = new RootBeanDefinition(bd);
}
}
else {
// 有父bean的情况
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
// 开始获取parentbean的名称
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 根据parent的名称获取合并的父bean 递归调用
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// 基于父亲来创建了一个RootBeanDefinition
// mbd 是基于pbd构造出来的,所以说mbd就是父亲
mbd = new RootBeanDefinition(pbd);
// 把孩子的属性和父亲的属性整合再一起
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
// 把完整合并后的bean放入到mergedBeanDefinitions这个map集合里面
// this.mergedBeanDefinitions 把父子合并的bean存放再这个map里面
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
5、进入到overrideFrom这个方法
public void overrideFrom(BeanDefinition other) {
// other传进来的是孩子
if (StringUtils.hasLength(other.getBeanClassName())) {
// 父亲再调用这个方法
// 查看this就可以得知this代表得是RootBeanDefinition合并后的
setBeanClassName(other.getBeanClassName());
}
if (StringUtils.hasLength(other.getScope())) {
setScope(other.getScope());
}
// 把孩子的抽象赋值给父亲 ,非抽象的才可以实例化
setAbstract(other.isAbstract());
setLazyInit(other.isLazyInit());
if (StringUtils.hasLength(other.getFactoryBeanName())) {
setFactoryBeanName(other.getFactoryBeanName());
}
if (StringUtils.hasLength(other.getFactoryMethodName())) {
setFactoryMethodName(other.getFactoryMethodName());
}
setRole(other.getRole());
setSource(other.getSource());
copyAttributesFrom(other);
if (other instanceof AbstractBeanDefinition) {
AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
if (otherAbd.hasBeanClass()) {
setBeanClass(otherAbd.getBeanClass());
}
if (otherAbd.hasConstructorArgumentValues()) {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
}
if (otherAbd.hasPropertyValues()) {
getPropertyValues().addPropertyValues(other.getPropertyValues());
}
if (otherAbd.hasMethodOverrides()) {
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
}
setAutowireMode(otherAbd.getAutowireMode());
setDependencyCheck(otherAbd.getDependencyCheck());
setDependsOn(otherAbd.getDependsOn());
setAutowireCandidate(otherAbd.isAutowireCandidate());
setPrimary(otherAbd.isPrimary());
copyQualifiersFrom(otherAbd);
setInstanceSupplier(otherAbd.getInstanceSupplier());
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
if (otherAbd.getInitMethodName() != null) {
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if (otherAbd.getDestroyMethodName() != null) {
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
setSynthetic(otherAbd.isSynthetic());
setResource(otherAbd.getResource());
}
else {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
getPropertyValues().addPropertyValues(other.getPropertyValues());
setResourceDescription(other.getResourceDescription());
}
}
2、创建对象的过程
1、进入到getSingleton这个方法 参数里面有个lab表达式 会去执行
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 去一级缓存中获取该对象 再次确认下单例池中有没有该对象
Object singletonObject = this.singletonObjects.get(beanName);
// 没有完整的存入在但单例池中
if (singletonObject == null) {
// 如果这个是在进行销毁操作,则抛出一个异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 创建之前
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 回调createbean()这个方法
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 创建完成之后怎么办
afterSingletonCreation(beanName);
}
// 如果你有一个新的单例
if (newSingleton) {
// 添加到单例池里面
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
2 、进入到 beforeSingletonCreation这个方法
protected void beforeSingletonCreation(String beanName) {
// 状态的判断,判断这个bean是不是被排除掉了 并且这个bean此时正在被创建中的状态
// 啥是排除
// 比如 在@ComponentScan(excludeFilter="") // excludeFilter就是排除哪些注解我不需要需要把他给排除掉
// 排除掉的bean则就不需要创建 在标签中也可以
// <context:component-scan base-package="">
// <context:exclude-filter type="" expression=""/> 排除,这里面的那些类我是不需要被扫描注解的从而创建对象的
// </context:component-scan>
// this.inCreationCheckExclusions.contains(beanName) 这个bean没有被排除
// this.singletonsCurrentlyInCreation.add(beanName) 这个bean此时正在被创建中的状态 ,
// 一旦标记为创建中的状态,后续当别的bean在需要我这个bean的时候,就不需要在创建了,
// 则之前从缓存体系中获取,这个是解决循环依赖的核心
/**
* 比如说我创建一个A,我在创建他的过程中放入到singletonsCurrentlyInCreation里面,此时说明A是正在被创建中,不一定被创建完成 创建完成的对象一定要经过创建,注入,初始化
* 如果后续我有个类,叫做B, B当时需要A的时候,首先B不会创建A了,去singletonsCurrentlyInCreation里面查找,如果队列里面有,则
* 说明A我已经正在被创建中了,B就不需要重新创建A了,只需要从队列里面去拿就行,正在创建中放队列的原因是为了解决循环依赖问题的
*
*/
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
3、进入到createBean()这个方法 会去调用doCreateBean()方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 获取bd对应的class信息
// 有BeanClass 就直接返回,没有BeanClass就直接通过反射获取class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 比如你在bean标记里面设置了 <lookup-method/> <replaced-method/>
/*
<bean id="p" class="com.dongdong.source.bean.Product">
<lookup-method/>
<replaced-method/>
</bean>
*/
// 该方法就是解决<lookup-method/> <replaced-method/> 方法替换
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 让 BeanPostProcessors 有机会返回一个代理而不是目标 bean 实例 这里的BeanPostProcessors不是我们所说的加工
// 加工的前提就是这个对象创建出来,注入属性,容器注入后才进行加工
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 核心方法创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
3、进入到doCreateBean()这个方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// BeanWrapper bean的包装,一方面肯定是包装了对象,另一方面肯定是对这个对象进行了一些功能性的扩展
// BeanWrapper的实现类里面的rootObject(包装的目标也就是我们要创建的那个对象)和rootClass(对象的类型)这两个属性,都会存储在这两个属性里面,除了这个两个属性之外,剩下的都是对他的好处,
//比如propertyValue这个属性,对象的属性会存储在里面,方便后期使用
// 问题 为什么要存储在Wrapper里面, 方便spring方便访问这些属性
// 1、一方面是对属性的填充,2、对这些属性进行类型转换(类型转换器)
// 类型转换器,把spring配置文件中的字符串信息,转换成对应对象属性的实际类型
// 实际的整个包装的BeanWrapper的核心就是要即把对象存起来,又把他的属性获取,同时还要匹配对应的类型转换器
// 类型转换器:内置类型转换器(String转成Integer String转成List String转成数组)
// 自定义类型转换器 比如 String ---> Date
// 类型转换器的开发
// 1、PropertyEditorSupport --> CustomeEditorConfigure
// 2、Converter接口 --> 类名称必须为conversionService
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建Bean的实例,并且进行了包装完成对象的创建,包装的原因不仅获取了实例相关的信息,而且还进行了类型转换器的封装
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取 bean对象
Object bean = instanceWrapper.getWrappedInstance();
// 获取的bean的class
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 一个没有创建完成的bean 值为true 说明此时有一个不完整的bean在被创建需要被保存在缓存中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 属性的填充(set注入,自动注入)
// 在配置文件中<bean></bean>标签可以指定autowire属性方式
// 或者在<beans></beans> 里面指定default-autowire
// 表示只要在这个标签里面的所有<bean></bean>标签都进行自动注入
populateBean(beanName, mbd, instanceWrapper);
// 初始化操作
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
4、进入到createBeanInstance、instantiateBean、instantiate、instantiateClass
// createBeanInstance方法()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// getFactoryMethodName 就是我们在配置文件定义的factory-method(静态工厂或者是实例工厂) 通过工厂来创建对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 被解析过的
boolean resolved = false;
// 自动的方式,
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 无参构造反射创建对象是spring的默认实现
return instantiateBean(beanName, mbd);
}
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
// 通过一个默认的创建策略来实例化,通过默认无参 反射创建对象
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 进行beanWrapper的封装,封装对象的信息,以及对类型转换器的封装
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
// 初始化BeanWrapper
initBeanWrapper(bw);
// 返回bw
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 获取类的class
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
// 获取构造器
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 实例化该类
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
// ctor.newInstance(args) 核心方法 传入 构造参数,调用构造方法创建对象
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
ConstructorAccessor ca = constructorAccessor; // read volatile
if (ca == null) {
ca = acquireConstructorAccessor();
}
@SuppressWarnings("unchecked")
// 对象实例化
T inst = (T) ca.newInstance(initargs);
return inst;
}
3、填充属性
1、进入 populateBean这个方法
// populateBean这个方法 set注入 创建对象的同时来进行构造注入 自动注入(源码忽略)
// XML
// <bean id="" class="">
// <property>
// JDK <proerty name="" value="">
// 自建 <proerty name="" ref="">
// </bean>
// 注解形式:
// @Autowired等同于 ref @Value等同于JDK类型 @Inject @Resources
// 进行类型的转换 内置和自定义都会在这里面调用
// 转换器在 bw里面 而对象的成员变量的数据在mbd中
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 安全校验 bw==null 说明这次属性填充是有问题
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 如果有PropertyValues 则取获取他里面的成员属性 后续基于PropertyValues开始属性的注入
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 自动注入的代码,基本不用
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 标志,来判断此时注入形式或者填充形式是否是注解,还是普通通过标签的形式
// 如果这个标志为true 则你是通过注解的形式进行注入
// 基于BeanPostProcessor完成的是基于注解的方式进行注入 @Autowired + @Value 基properties文件
// 用的那个BeanPostProcessor --> AutowiredAnnotationBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 当获取的是AutowiredAnnotationBeanPostProcessor这个类
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//类型为AutowiredAnnotationBeanPostProcessor,这行代码会进行转换
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
// 检查:比如我对象需要依赖一个别的对象的属性,你是否给我赋值,一般这个标志位为false
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 非注解的属性填充
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取于注入相关的信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 完成注解处理
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// 遍历拿到元素的属性,id,name什么 一个属性一个属性的遍历
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
// 进入到这个方法
element.inject(target, beanName, pvs);
}
}
}
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 元素的id值
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 获取@Value里面填写内容的值
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
// 因为属性可能是私有的,如果想对其进行赋值的打破封装,表示允许你访问
ReflectionUtils.makeAccessible(field);
// 反射赋值 value就是获取的值,field就是id
field.set(bean, value);
}
}
}
2、进入到applyPropertyValues方法 基于非注解方式填充
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
// PropertyValues 都是 MutablePropertyValues
MutablePropertyValues mpvs = null;
// original 原始 没有进行类型转换的数据
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 如果是被转换过的走这个分支
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
// 从MutablePropertyValues里面获取对象的属性
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
//获取自定义类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
// 把bw里面的类型转换器赋值给了这变量
converter = bw;
}
// 获得一个转换器,把Spring封装数据类型 TypeStringValue解析成实际java的原始类型
// TypeStringValue针对的是jdk类型的封装
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
// 标记转换完成的标记 为true表示转换完成
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
// 获取名称
String propertyName = pv.getName();
// 所有在配置文件读出来的文件数据在spring当中都会封装成TypeStringValue 里面会有对应的值
// TypeStringValue针对的是jdk类型的封装 如果是RuntimeBeanReference 是我们自定义的类型,后面经过转换后成为具体的那个bean
// 如果Spring在处理的过程中发现RuntimeBeanReference类型咋处理呢?
// Spring 一定会为这个自定义类型进行set注入,但是前提你的有这个对象才可以,
// 所以Spring最终肯定会从工厂里调用getBean ---> doGetBean ---> createBean ---> doCreateBean
Object originalValue = pv.getValue();
// 通过转换后单独拿出来一个值 把他从一个封装的类中提取出来 还没到类型转换
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// bw.isWritableProperty(propertyName) 是不是可写的,比如你在属性上加了final关键字
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
// 真正进行转换了,把拿到的字符串,和对应的名称,还有beanWapper以及对应的转换器得到转换后的值
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
// 前面一个是spring里面所有的value值类型是个数组,而后面是单个,肯定不相等
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
// 转换完成 还没进行赋值 把对应的类型与属性配对好
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
// 标记转换已经转换完成了
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// 走到这里,才把转换好的值赋值给对应的bean
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
4、初始化操作
1、进入到 initializeBean这个方法
// initializeBean这个方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 容器注入aware 也是set注入的一种 设置了BeanNameAware和BeanFactoryAware和BeanClassLoaderAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 初始化前 调用BeanPostProcessorsBeforeInitialization对对象进行加工后返还给spring工厂
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 初始化 其中通过实现接口的方式初始化和用户自定义方法初始化 返还给BeanPostProcessors
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 初始化后 调用BeanPostProcessorsAfterInitialization来得到一个完整可以给调用者使用的
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
5、进入invokeInitMethods()这个方法
// invokeInitMethods方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 判断是不是InitializingBean实例
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 调用afterPropertiesSet这个方法初始化 这个方法在前 这就是为啥你写了自定义方法和实现了
// InitializingBean这个接口 如果两个同时存在接口这个方法会在前
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
// 获取InitMethod的名字
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用init-method定义的标签初始化
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
6、进入invokeCustomInitMethod()
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
// 通过方法名称获取这个方法
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> methodToInvoke.invoke(bean), getAccessControlContext());
}
catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
}
else {
try {
// 设置方法访问的权限
ReflectionUtils.makeAccessible(methodToInvoke);
// 调用该方法
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
Spring中的循环引用问题
结论 :
- 两个对象都是单实例的情况下,且通过set方式进行注入才能成功
- 两个对象都是单实例的情况下,且通过构造方法进行注入不可以
- 两个对象都是多实例的情况下,不管使用set还是构造注入,都不可以
源码分析
// 在doCreateBean 这一段代码
// 一个没有创建完成的bean 值为true 说明此时有一个不完整的bean在被创建需要被保存在缓存中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 添加到SingletonFactory缓存中,没完整体的对象
// 这里为啥传入的是一个bean的方法呢? 因为这里要进行代理,要进行AOP
// 调用过程中创建代理,把对应的代理对象 放在在代理缓存池中
// 如果有代理则执行getEarlyBeanReference,没则直接把对象返回了
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 存储不完整体: 假设a
// 存储在SingletonFactory a 不完全体A的对象
// 实际上存储 a -> AbstractAutowireCapableBeanFactory$$Lambda$13/630074945@1800a575 lam表达式
// 之所以不存,一个不完整的A对象,而存储一个方法,存储方法意味着可以处理复杂的功能
// 比如说我这里需要获取A的代理对象,但是我这个a是一个不完全体的对象,如果说要获取A的代理对象,必须要依托于beanpostprocessors 但是获取代理对象是在初始化后获取,显然我们这个A还没到初始化,所以这里传入一个方法的作用在于
// 如果你获取的对象是个代理对象就交给这个方法完成
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 安全校验,没有存在单例池中
if (!this.singletonObjects.containsKey(beanName)) {
// 放入到singletonFactories 这个缓存中
// 存放bean的名称,bean的工厂
this.singletonFactories.put(beanName, singletonFactory);
// 把bean从earlySingletonObjects移除掉,因为已经存储在上面的缓存中,没必要在存储一份
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 遍历所有的beanpostprocessors 这里可以创建代理对象
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
// 返回该对象或者该代理对象
return exposedObject;
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 第一次从这个map中获取对象 一级缓存 他先被调用
Object singletonObject = this.singletonObjects.get(beanName);
// 如果获取的对象为null
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 第二次获取 预先单例池 二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果获取还是为null
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
// 再进行获取 单例工厂池 三级缓存
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 从缓存中获取对象,
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 如果获取到了
if (singletonFactory != null) {
// 则回调getEarlyBeanReference拿到代理对象,并且把代理对象放入代理池中 代理池是单独的
singletonObject = singletonFactory.getObject();
// 把回调getEarlyBeanReference拿到代理对象或者是普通对象放入第二个池子里面
// 这里准确来讲存放的是lamba表达式运行结果
// 可能后期可能我不做代理,就不走这个getEarlyBeanReference方法,
// 代理只是为方法添加功能,而不对属性的赋值操作
this.earlySingletonObjects.put(beanName, singletonObject);
// 把获得到的对象从第三个池中移除掉
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
DefaultListableBeanFactory
- Spring 核心容器(对象的创建,存储,注入)具体的实现方法是在AbstractAutowireCapableBeanFactory
- AbstractAutowireCapableBeanFactory 子类 DefaultListableBeanFactory
ApplicationContext(编程时使用)
-
也是对BeanFactory 子接口 具有BeanFactroy对应的功能
-
也是针对BeanFactory的扩展
-
ApplicationContext 是没有继承 xxxRegist 注册 存储 bean
- 通过子类或子接口实现 xxxRegist 从而具有xxxRegist
- 子类 组合(聚合) DefaultListableBeanFactory 同样具备了xxxRegist功能
- 继承要满足 一个前提 那就是is a 的关系 比如 一个 人 想拥有 车的功能 显然是不现实的问题
- 如果我们要采用复用,可以通过聚合 或者 组合的方式完成,比如 a 我想拥有 b的功能 我可以人让 b成为我的属性 访问通过提供的方法(构造函数)来进行 如果是线程不安全的环境下,让 b 成为我方法的参数 通过传递参数来实现b的功能
-
BeanFactory 创建对象的时候是现用现创建(lazy),而ApplicationContext 默认是预先创建对象
-
AC 底层还是通过BeanFactory,如何做到预先创建
- Ac 创建过程中 由AC手工调用BeanFactory.getBean() —> 存储到singletonObject
BeanDefinition
- 创建有三种方式 ps 今后我们说的注册 注册包括创建
-
Xml 读取 配置文件 注册(创建BeanDefinition)注册BeanDefinition 封装到map里
-
基于 Annotated(带注解的类) 也就类的方式 注册(创建BeanDefinition) 注册BeanDefinition 封装到map里
-
// 带注解的类 AnnotatedGenericBeanDefinition bd = new AnnotatedGenericBeanDefinition(beanClass); // 不带注解的类 GenericBeanDefinition bd = new GenericBeanDefinition(beanClass);
-
-
手动设置BeanDefinition 后期是一个非常重要的扩展点 BeanPostProcessor 比如第三方框架需要整合spring也是一大扩展点
-
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Test1.class);
GenericBeanDefinition beanDefinition = (GenericBeanDefinition) beanDefinitionBuilder.getBeanDefinition();
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
// 采用set注入
propertyValues.add("password",123);
/*System.out.println("beanDefinition = " + beanDefinition);*/
// 采用构造注入
ConstructorArgumentValues constructorArgumentValues = beanDefinition.getConstructorArgumentValues();
constructorArgumentValues.addArgumentValues(null);
Spring 注册bean的几种方式
-
基于xml 进行注册
-
基于注解 @Configuration @Compontent 以及他的衍生 注解 @Controller @Service 等,
-
@Bean
-
这种方式目前Spring在开发过程建议我们使用的注册方式,这种注册类型的特点,别的框架(非Spring)组件,提供的类型
-
Mybatis:SqlSessionFactory.class SqlSessionFactory{ } @Configration public class AppConfig{ @Bean public sqlSessionFactory createSqlSessionFactory(){ xxxxxxx return } @Bean public DataSource createDataSource(){ xxxxxx } }
-
-
@Compontent 和 @Bean区别
- @Bean 适用于第三方框架整合Spring 注册到spring中使用
-
-
ClassPathBeanDefinitionScanner扫描特定路径下的具有注解的Bean进行注册
-
两者的区别 AnnotationConfigApplicationContext(AppConfig.class) 先去寻找配置bean 然后在进行包的扫描,而下面是直接进行包扫描 AnnotationConfigApplicationContext(AppConfig.class) AnnotationConfigApplicationContext("com.xxx") 底层基于ClassPathBeanDefinitionScanner来进行包的扫描
-
-
@Import 注解 三种形式
-
@Import注解中直接放入对应类 基本不用,不常用原因:可以通过注解的方式进行对应类型的注册
-
ImportSeletor @Import(MyImportSelector.class)
-
// 不要忘了在需要该类中添加 @Import(MyImportSelector.class) public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{User.class.getName()}; } } // 目的 为了封装 使用 好处 不像最终用户 暴露 细节 // 应用场景 存在实际的.class 大部分使用该类型,对外提供个注解 内部实现我们看不到
-
-
ImportBeanDefinitionRegister @Import(MyImportBeanDefinitionRegister.class)
-
// 不要忘了在虚高该类中添加 @Import(MyImportBeanDefinitionRegister.class) public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { beanDefinitionRegistry.registerBeanDefinition("",null); } } // 不存在实际.class 需要动态字节码技术 运行创建的类型 JDK Cglib ASM Javasist
-
-
Spring整合Mybatis
// 基于注解 Spring
配置 注解完成
@Configuration
@MapperScanner(“dao接口在的包”)
public class MybatisConfig{
@Bean
public DataSource createDataSource(){
return datasource;
}
@Bean
public SessionFactoryBean createSessionFactoryBean(){
xxxxx
return ;
}
}
// Mybatis 这些对应mybatis中的
/*
InputStream = Resources.getResoruceAsStream("");
SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream)
SqlSession = sqlSessionFactory.openSession();
*/
@Bean
public DataSource createDataSource(){
return datasource;
}
@Bean
public SessionFactoryBean createSessionFactoryBean(){
xxxxx
return ;
}
// mybatis
@MapperScanner(“dao接口在的包”) 对应 mybatis 中的
// UserDAO的实现类 是通过JDK动态代理创建的
UserDAO userDao = SqlSession.getMapper("UserDAO.class")
模拟Spring 整合 Mybatis
-
mybatis 最后会创建一个代理对象来进而操作mapper接口 ,mapper接口的实现类是在spring运行的时候动态创建出来的
-
准备一个配置类
@Configuration @ComponentScan(basePackages = {"com.dongdong.source.mybatis"}) @Import(MyImportRegister.class) public class AppConfig { }
-
dao service serviceImpl 这些
-
准备一个MyImportRegister 这个 类 继承 ImportBeanDefinitionRegistrar 来创建注册bean
public class MyImportRegister implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { // 创建userDAO的代理 代理的类型我们是获取不了的,代理在运行的时候才创建,我们需要把代理的类型封装到一个类中 // 封装成一个FactoryBean // UserDAO userDao = Proxy.newProxyInterface() // 创建BD // 这里的BD 是FactoryBean的BD 我们需要创建这个代理,依托于FactoryBean 我们把创建代理的逻辑写在FactoryBean的getObject spring // 会自动帮我们调用从而生成userDao的代理实现类 BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyFactoryBean.class); GenericBeanDefinition beanDefinition = (GenericBeanDefinition) builder.getBeanDefinition(); // 进行注册 beanDefinitionRegistry.registerBeanDefinition("userDAO",beanDefinition); } }
-
准备一个MyFactoryBean 实现 FactoryBean 来创建 userDAO的代理实现类
// @Component // 这里不需要在加Component 我们加这个注解就是为了让spring注册该bean 但是我们手动通过 // BeanDefinitionBuilder.genericBeanDefinition(MyFactoryBean.class) 进行了注册,所以不需要添加 添加反而报错 public class MyFactoryBean implements FactoryBean<UserDAO> { // spring 在运行的时候会回调 getObject这各个方法 @Override public UserDAO getObject() throws Exception { UserDAO userDAO = (UserDAO) Proxy.newProxyInstance(MyFactoryBean.class.getClassLoader(),new Class[]{UserDAO.class},(Object proxy, Method method, Object[] args) -> { System.out.println("这是UserDAO的实现类"); return null; }); return userDAO; } @Override public Class<?> getObjectType() { return UserDAO.class; } }
-
测试
public class Test1 { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); UserService userService = (UserService) ctx.getBean("userServiceImpl"); userService.register(); } } // 这是UserDAO的实现类
Spring 核心方法 refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 设置启动日期和活动标注
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 创建 BeanFactory 默认是 DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备AC applicationContext 配置工厂的标注上下文特征,;例如上下文ClassLoader(创建对象或者代理对象)和后置处理器
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 空的实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 实例化并使用所有注册的BeanFactoryPostProcessor Bean,并遵循显示顺序,必须在单例实例化之前
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册后置处理bean
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 处理消息
initMessageSource();
// Initialize event multicaster for this context.
// 处理事件
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 处理特殊的bean 和子的工厂
onRefresh();
// Check for listener beans and register them.
// 注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例所有的单例对象
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 处理类型转换器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
// 获取字符串类型的转换器
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 设置一些类加载器
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 冻结配置,不允许配置改变
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化所有的单例
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons 核心方法
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 获取所有beanDefinition 的名字
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 获取合并的bd 父子bean getMergedLocalBeanDefinition 解决父子bean配置合并的问题
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是一个抽象 ,是一个单实例 是一个立即被加载的 满足我就创建
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
SpringMVC 处理请求的流程
会经过doDispath这个方法在里面执行请求流程
1、首先用户的发送了一个请求,都会经过DispatcherServlet ,DispatcherServlet会拦截所有的请求,DispatcherServlet接收到请求后会去寻找一个可以解析我用户路径的这么一个处理器叫做HandlerMapping 处理器映射器,找到一个合适的HandlerMapping 来解析路径
2、返回给DispatcherServlet,DispatcherServlet 接着又会根据用户的路径找到对应的Handler方法来处理用户这个请求,所以此时又会去寻找一个HandlerAdapter 处理器适配器 来处理handler方法解析我们的参数值,如果在此时配置了前置拦截器会去执行拦截器的逻辑,如果执行拦截器的逻辑返回false的话那么整个doDispath这个方法会退出,后面就会真正去执行我们的目标方法了解析我们的返回值,返回一个ModelAndView,视图解析器对象,并且最终返回给 DispatcherServlet
3、返回给DispatcherServlet后,会去调用后置拦截器,如果没配置的话则不执行,后就进行视图名称的解析,调用viewResolvers 视图解析器去解析视图名称,返回View 视图并返回给 DispatcherServlet
4、返回给DispatcherServlet后,会去渲染视图,并且响应给客户端,会调用最终的拦截器
yBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
# SpringMVC 处理请求的流程
> **会经过doDispath这个方法在里面执行请求流程**
1、首先用户的发送了一个请求,都会经过**DispatcherServlet** ,**DispatcherServlet**会拦截所有的请求,**DispatcherServlet**接收到请求后会去寻找一个可以解析我用户路径的这么一个处理器叫做**HandlerMapping** 处理器映射器,找到一个合适的**HandlerMapping** 来解析路径
2、返回给**DispatcherServlet**,**DispatcherServlet** 接着又会根据用户的路径找到对应的Handler方法来处理用户这个请求,所以此时又会去寻找一个**HandlerAdapter** 处理器适配器 来处理handler方法解析我们的参数值,如果在此时配置了前置拦截器会去执行拦截器的逻辑,如果执行拦截器的逻辑返回false的话那么整个doDispath这个方法会退出,后面就会真正去执行我们的目标方法了解析我们的返回值,返回一个**ModelAndView**,视图解析器对象,并且最终返回给 **DispatcherServlet**
3、返回给**DispatcherServlet**后,会去调用后置拦截器,如果没配置的话则不执行,后就进行视图名称的解析,调用**viewResolvers** 视图解析器去解析视图名称,返回**View** 视图并返回给 **DispatcherServlet**
4、返回给**DispatcherServlet**后,会去渲染视图,并且响应给客户端,会调用最终的拦截器