Bean的生命周期

 

这里要先了解Bean的后置处理器(BeanProstProcessor):

我们可以理解为大多数情况下在创建了对象之后,可以进行对对象的其他操作,再转化成Bean

@Component
public class FactoryBeanProstProcessor implements BeanPostProcessor {

    
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }


}

使用后置处理找到对应类中属性的注解

就相当于对这个对象进行处理(赋值等等...)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface LuoLuo  {

    String value();
}

@ComponentScan("com.test")//扫描路径
public class Config {

}

@Component
public class FactoryBeanProstProcessor implements BeanPostProcessor {
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> clazz = bean.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(LuoLuo.class)){
                LuoLuo fieldAnnotation = field.getAnnotation(LuoLuo.class);//得到这个属性上的注解
                String s = fieldAnnotation.value();//讲注解赋值给s
                System.out.println(s);
            }
        }
        return null;
    }
}
public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);//通过Config配置得到对象
        UserService userService = (UserService) context.getBean("userService");
        System.out.println(userService);

    }

最后输出
xiaoluoxxx

实例化

@ComponentScan("com.user")
public class Config {
}
@Component
public class UserService {
    public UserService() {
        System.out.println("我是无参构造");
    }
}

 public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        UserService userService = context.getBean("userService", UserService.class);
        System.out.println(userService);
    }

我是无参构造
com.user.UserService@42607a4f

实例化前

@Component
public class LLBeanPostProcess implements InstantiationAwareBeanPostProcessor {

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            System.out.println("实例化前");
        }
        return null;
    }
    
    实例化前
    我是无参构造
com.user.UserService@6fb0d3ed

如果实例化前给他直接返回一个对象,那么就不会再进行实例化

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    if (beanName.equals("userService")){
        System.out.println("实例化前");
    }
    return new UserService();
}

实例化和推断构造方法

@Component
public class UserService {

    private User user;

    public UserService(User user) {
        this.user=user;
        System.out.println("一个有参构造");
    }
}

只有一个有参构造就直接调用
一个有参构造


@Component
public class UserService {

    private User user;

    public UserService(User user) {
        this.user=user;
        System.out.println("一个有参构造");
    }
    

    @Autowired//必须的必要的
    public UserService(User user,User user1) {
        this.user=user;
        System.out.println("二个有参构造");
    }
    
    二个有参构造
        
   有两个有参就会报错,但是只要给他一个注解,他就会自动判断有注解的哪一个
       
       
        @Autowired(required = false)
    public UserService(User user) {
        this.user=user;
        System.out.println("一个有参构造");
    }


    @Autowired(required = false)
    public UserService(User user,User user1) {
        this.user=user;
        System.out.println("二个有参构造");
    }

    按照自己的逻辑会选一个构造方***先选参数多的
    如果一样多就会按顺序选择.
       

实例化后

@Component
public class LLBeanPostProcess implements InstantiationAwareBeanPostProcessor {

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        return null;
    }

    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            System.out.println("我是后置");
        }
        return true;
    }
}

@Component
public class UserService {

    private User user;

    public UserService() {
        System.out.println("我是无参构造方法");
    }

    @Autowired
    public void setUser(User user) {
        System.out.println("set方法注入");
        this.user = user;
    }
}

我是无参构造方法
我是后置
set方法注
    
    我们可以在实例化后操作这个对象的属性
    
    

初始化

@Component
public class UserService implements InitializingBean {

    private User user;

    public UserService() {
        System.out.println("我是无参构造方法");
    }

    @Autowired
    public void setUser(User user) {
        System.out.println("set方法注入");
        this.user = user;
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化");
    }
}

我是无参构造方法
我是后置
set方法注入
初始化
    
    @Component
public class UserService implements InitializingBean {

    private User user;

    @PostConstruct
    public void xxx(){

        System.out.println("xxx");
    }

    public UserService() {
        System.out.println("我是无参构造方法");
    }

    @Autowired
    public void setUser(User user) {
        System.out.println("set方法注入");
        this.user = user;
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化");
    }
}

我是无参构造方法
我是后置
set方法注入
xxx
初始化
    
    @PostConstruct
    利用初始化前的这个注解,可以进行其他操作
    <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>

初始化会在Spring自动注入后面才会执行,我们可以在里面修改我们想修改的都可以

初始化前

   @PostConstruct
    public void xxx(){

        System.out.println("xxx");
    }

@Component
public class LLBeanPostProcess implements InstantiationAwareBeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            System.out.println("初始化前");
        }
        return null;
    }
}


我是无参构造方法
set方法注入
初始化前
初始化
com.user.UserService@3439f68d
    
    
    @Component
public class LLBeanPostProcess implements InstantiationAwareBeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            System.out.println("初始化前");
        }
        return bean;
    }
}

我是无参构造方法
set方法注入
初始化前
xxx
初始化
com.user.UserService@3439f68d

这里我们的xxx方法上面的注解就相当于一个postProcessBeforeInitialization

LLBeanPostProcess------>postProcessBeforeInitialization 当方法返回null时,这里就起到一个中断的作用,前面的实例化全部都做完了,如果返回一个bean对象,初始化前方法就会把bean对象传到下一个方法中!

@PostConstruct------>postProcessBeforeInitialization 前面有对象返回的时候才有效!

验证

@Component
public class LLBeanPostProcess implements InstantiationAwareBeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            System.out.println("初始化前");
            for (Method method : bean.getClass().getMethods()) {
                if (method.isAnnotationPresent(PostConstruct.class)){
                    try {
                        method.invoke(bean);//如果这个方法上面有这个注解就再执行一次
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return bean;
    }
}

我是无参构造方法
set方法注入
初始化前
xxx
xxx
初始化
com.user.UserService@3439f68d

初始化后

  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            System.out.println("初始化后");
        }
        return bean;
    }
    
我是无参构造方法
set方法注入
初始化前
xxx
xxx
初始化
初始化后
com.user.UserService@3439f68d

我们就可以在这里面进行多态代理,也就是AOP,下面我们来进行一下模拟

package com.user;

public interface UserInterface {

    public void test();
}


public class UserService implements InitializingBean ,UserInterface{

 public void test() {
        System.out.println("业务逻辑");
    }
}

public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            Object o = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                    System.out.println("动态代理");
                    return null;
                }
            });
            return o;
        }
        return bean;
    }
    
public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        UserInterface userService = (UserInterface) context.getBean("userService");
        userService.test();
    }

我是无参构造方法
set方法注入
初始化前
xxx
xxx
初始化
动态代理


//这个bean就时userService对象,我们在初始化后方法中可以讲这个bean对象替换掉,替换成我们这个动态代理的代理类,相当于狸猫换***。我们想要先执行我们的代理逻辑,再执行传入的userService对象的对应的method方法。

 public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")){
            Object o = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                    System.out.println("代理逻辑1");
                    method.invoke(bean,objects);
                    System.out.println("代理逻辑2");
                    return null;
                }
            });
            return o;
        }
        return bean;
    }
    
我是无参构造方法
set方法注入
初始化前
xxx
xxx
初始化
代理逻辑1
业务逻辑
代理逻辑2

也是我们Spring实现aop的基本逻辑。

#java求职##学习路径#
全部评论
我顶
点赞 回复 分享
发布于 2021-10-20 19:29
这么好的帖子没人顶
点赞 回复 分享
发布于 2021-10-05 19:26

相关推荐

评论
3
30
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务