spring源码学习(二)spring复习之bean实例化、生命周期、循环依赖

1 实例化的基本流程

image
image

image
BeanDefinition默认实现类,GenericBeanDefinition
image
示例

public class UserServiceImpl implements UserService {
    public void setUserDao(UserDao userDao){
        System.out.println("set注入userDao:"+userDao);
    }
}
    <beans>
        <bean id="UserService" class="com.cdc.service.impl.UserServiceImpl">
            <property name="userDao" ref="userDao"></property>
        </bean>
        <bean id="userDao" class="com.cdc.dao.impl.UserDaoImpl"></bean>
    </beans>
public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService =(UserService) applicationContext.getBean("UserService");
        System.out.println(userService);
    }
}

查看GenericBeanDefinition里面的属性
image
还有其资源是哪个
image

2 spring后处理器

image

2.1 BeanFactoryPostProcessor

image

2.1.1改变bean

改变名为"userService"的bean,改其全限定名为“com.cdc.dao.impl.UserDaoImpl”,让其后面实例化时,实例为UserDaoImpl对象,不是配置好的UserServiceImpl对象

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
        beanDefinition.setBeanClassName("com.cdc.dao.impl.UserDaoImpl");
    }
}
    <beans>
        <bean id="userService" class="com.cdc.service.impl.UserServiceImpl"></bean>
        <!--配置后置处理器-->
        <bean class="com.cdc.processor.MyBeanFactoryPostProcessor"></bean>
    </beans>
public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Object userService = applicationContext.getBean("userService");
        System.out.println(userService);
    }
}

输出:

com.cdc.dao.impl.UserDaoImpl@56ac3a89

2.1.2添加bean

xml文件里没有配置任何的bean,通过后置处理器,添加(注册)bean

public class MyBeanFactoryPostProcessor2 implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClassName("com.cdc.service.impl.UserServiceImpl");
        DefaultListableBeanFactory defaultListableBeanFactory=(DefaultListableBeanFactory) beanFactory;
        defaultListableBeanFactory.registerBeanDefinition("userService",beanDefinition);
    }
}
  • 这里的beanFactory默认就是DefaultListableBeanFactory对象
    <beans>
        <!--配置后置处理器-->
        <bean class="com.cdc.processor.MyBeanFactoryPostProcessor2"></bean>
    </beans>
  • xml文件里没有配置任何的bean

测试文件

public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Object userService = applicationContext.getBean("userService");
        System.out.println(userService);
    }
}

输出

com.cdc.service.impl.UserServiceImpl@490ab905

2.1.3

image
image
image
image

2.2 BeanPostProcessor

image

2.2.1示例

public class MyBeanPostProcessor implements BeanPostProcessor {

    //这个方法是选择性实现,也可以不实现
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof UserServiceImpl){
            UserServiceImpl userService= (UserServiceImpl)bean;
            userService.setUserPro("哈哈哈");
            System.out.println("before");
        }
        return bean;
    }

    //这个方法是选择性实现,也可以不实现
    //这段方法执行后,将对象放进单例池里
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof UserServiceImpl){
            UserServiceImpl userService= (UserServiceImpl)bean;
            System.out.println("after");
        }
        return bean;
    }
}
  • 注意上面俩方法的入参Object bean,这里的bean是所有的配置了的bean,这意味着可以对这些bean进行处理(或者增强),aop就是这么实现的
public class UserServiceImpl implements UserService , InitializingBean {

    private String userPro;

    public String getUserPro() {
        return userPro;
    }

    public void setUserPro(String userPro) {
        this.userPro = userPro;
    }

    public UserServiceImpl() {
        System.out.println("构造方法");
    }

    public void setUserDao(UserDao userDao){
        System.out.println("set注入userDao:"+userDao);
    }

    public void userInit(){
        System.out.println("userInit");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
}
    <beans>
        <bean id="userService" class="com.cdc.service.impl.UserServiceImpl" init-method="userInit">
            <property name="userDao" ref="userDao"></property>
        </bean>
        <bean id="userDao" class="com.cdc.dao.impl.UserDaoImpl"></bean>
        <!--  配置自己实现的bean后处理器MyBeanPostProcessor   -->
        <bean class="com.cdc.processor.MyBeanPostProcessor"></bean>

    </beans>
public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserServiceImpl userService = (UserServiceImpl)applicationContext.getBean("userService");
        System.out.println(userService.getUserPro());

    }
}

输出:可以看出先后执行顺序,先实例化,在set注入,再依次执行

构造方法
set注入userDao:com.cdc.dao.impl.UserDaoImpl@59494225
before
afterPropertiesSet
userInit
after
哈哈哈

2.2.2 示例 使用BeanPostProcessor 增强bean,模拟aop的情况

public class ShopServiceImpl implements ShopService {

    @Override
    public void show() {
        System.out.println("show......");
    }
}
public class MyBeanPostProcessor2 implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Object beanProxy = Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                ((proxy, method, args) -> {
                    System.out.println("增强show 前...");
                    Object result = method.invoke(bean, args);
                    System.out.println("增强show 后...");
                    return result;
                }));
        return beanProxy;
    }
}
    <beans>
        <bean id="shopService" class="com.cdc.service.impl.ShopServiceImpl"></bean>

        <bean class="com.cdc.processor.MyBeanPostProcessor2"></bean>
    </beans>
public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        ShopService shopService = (ShopService)applicationContext.getBean("shopService");
        shopService.show();
    }
}

输出:

增强show 前...
show......
增强show 后...

3 生命周期

image

3.1

这个阶段会通过反射创建对象,源码里有很多的if else判断,是无参构造还是有参构造,是不是延迟加载(是延迟加载就先不创建),是不是静态工厂方法创建,是不是实例化工厂方法创建等等
image
此时创建的bean,是半成品。看下图,此时实例化了UserServiceImpl,还没属性填充(set注入userDao),所以它就是个半成品。
image

3.2

image

3.3

image

image

3.4完整的生命周期

3.4.1单例模式下,spring管理bean的生命周期

CarServiceImpl类

public class CarServiceImpl implements CarService , InitializingBean , 
BeanNameAware, BeanClassLoaderAware, 
BeanFactoryAware,ApplicationContextAware,DisposableBean {
    public CarServiceImpl(){
        System.out.println("1. CarServiceImpl实例化构造");
    }
    public void setUserDao(UserDao userDao){
        System.out.println("2. set");
    }
    @Override //BeanNameAware
    public void setBeanName(String beanName) {
        System.out.println("3.1 beanName:"+beanName);
    }
    @Override //BeanClassLoaderAware
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("3.2 :"+classLoader);
    }
    @Override //BeanFactoryAware
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("3.3: "+beanFactory);
    }
    @Override//ApplicationContextAware
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("3.4: "+applicationContext);
    }  
    @Override //InitializingBean
    public void afterPropertiesSet() throws Exception {
        System.out.println("5. afterPropertiesSet");
    }
    //配置里的init-method
    public void initBean(){
        System.out.println("6. initBean");
    }
    @Override //DisposableBean
    public void destroy() throws Exception {
        System.out.println("9. destroy");
    }
    //配置里的destroy-method
    public void destroyBean(){
        System.out.println("10. destroyBean");
    }
}

bean后置处理器类MyBeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {

    //这个方法是选择性实现,也可以不实现
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof CarService){
            System.out.println("4. BeanPostProcessor before");
        }
        return bean;
    }

    //这个方法是选择性实现,也可以不实现
    //这段方法执行后,将对象放进单例池里
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof CarService){
            System.out.println("7. BeanPostProcessor after");
        }
        return bean;
    }
}

xml配置文件:

    <beans>
        <bean id="carService" class="com.cdc.service.impl.CarServiceImpl" init-method="initBean" destroy-method="destroyBean">
            <property name="userDao" ref="userDao"></property>
        </bean>
        <bean id="userDao" class="com.cdc.dao.impl.UserDaoImpl"></bean>
        <bean class="com.cdc.processor.MyBeanPostProcessor"></bean>
    </beans>

测试类:

public class ApplicationContextTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        CarService carService = applicationContext.getBean("carService", CarService.class);
        System.out.println("8. 使用carService :"+carService);
        applicationContext.close();
    }
}

输出:

1. CarServiceImpl实例化构造
2. set
3.1 beanName:carService
3.2 :sun.misc.Launcher$AppClassLoader@22d8cfe0
3.3: org.springframework.beans.factory.support.DefaultListableBeanFactory@327b636c: defining beans [carService,userDao,com.cdc.processor.MyBeanPostProcessor#0]; root of factory hierarchy
3.4: org.springframework.context.support.ClassPathXmlApplicationContext@64c64813, started on Tue Mar 10 18:00:19 CST 2026
4. BeanPostProcessor before
5. afterPropertiesSet
6. initBean
7. BeanPostProcessor after
8. 使用carService :com.cdc.service.impl.CarServiceImpl@47eaca72
9. destroy
10. destroyBean

3.4.1原型模式下,spring管理bean的生命周期,少了上面的9和10

原型模式

    <beans>
        <bean id="carService" class="com.cdc.service.impl.CarServiceImpl" init-method="initBean" destroy-method="destroyBean" scope="prototype">
            <property name="userDao" ref="userDao"></property>
        </bean>
        <bean id="userDao" class="com.cdc.dao.impl.UserDaoImpl"></bean>
        <bean class="com.cdc.processor.MyBeanPostProcessor"></bean>
    </beans>

4 属性注入

image

4.1单向对向引用属性的情况

image
image

image
image

image
image

posted @ 2026-03-08 14:57  dvdhellohaha  阅读(13)  评论(0)    收藏  举报