首页 > 其他分享 >bean的创建生命周期

bean的创建生命周期

时间:2022-11-05 23:14:49浏览次数:59  
标签:初始化 生命周期 对象 创建 bean UserService 方法 public

spring创建对象

UserService.class ->无参构造方法->得到对象->依赖注入(属性赋值)->初始化前方法(@PostConstruct)->初始化方法(InitializingBean)->初始化后(AOP)->bean

  • 默认调用类的无参构造方法,得到一个对象,此时对象内的其他属性还没有值,属性的赋值(加上@AutoWire注解)通过依赖注入来完成,伪代码:
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(SpringDemoApplication.class);
        UserService userService =(UserService) context.getBean("userService");
        for (Field field : userService.getClass().getFields()) {
            if (field.isAnnotationPresent(Autowired.class)){
                field.set(?,?);
            }
        }

随后会进行初始化前,初始化,初始化后方法

  • 初始化前方法(@PostConstruct)
    eg:在程序启动时从数据库加载信息,给bean的对象属性进行赋值操作,在UserService真正成为一个Bean之前完成对象的属性的填充(调用a()方法)。
    @Autowired
    private User admin;

    @PostConstruct
    public void a(){
        //mysql->User对象->admin
    }

spring调用初始化前方法之前判断哪些方法上加了@PostConstruct注解,执行方法完成对象的初始化前方法。

AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(SpringDemoApplication.class);
        UserService userService =(UserService) context.getBean("userService");

        for (Method method : userService.getClass().getMethods()) {
            if (method.isAnnotationPresent(PostConstruct.class)){
                method.invoke(userService,null);
            }
        }
  • 初始化
    UserService实现InitializingBean接口,重写afterPropertiesSet()方法,spring根据 UserService instance of InitializingBean判断对象是否实现了InitializingBean接口,随机对对象进行强制转换成对应的接口类型,随即执行afterPropertiesSet()方法,(InitializingBean)UserService.afterPropertiesSet();

spring源码实现:

  • 初始化后(AOP)
    对象的AOP相关方法会在初始化后进行,若对象的某个方法需要进行AOP相关操作,会为真实对象生成一个代理对象,对真实对象的相关方法的调用会代理对象的增强方法,最终代理对象会成为真正的bean。

推断构造方法:一个构造方法的时候,使用这一个构造方法,默认无参或者自定义的有参。
程序员指定了构造方法入参值,通过getBean或者BeanDefinition去传入参数,使用匹配参数的的构造。

  • 有参构造的对象的值(OrderService),从spring容器中获取,对象的获取先根据对象的类型寻找,若只有一个,则直接注入,也可能会找到多个对象,再根据对象的名称从容器中寻找出唯一的对象。若有两个相同类型,名字的bean,则@Bean对象会覆盖@Component对象

给@Autowire的对象的属性赋值,原理和上面类似,先bytype,再byname

初始化后AOP:

此时使用的是cglib的动态代理,会为UserService生成一个代理类(UserServiceProxy),重写父类的方法,并做方法的增强。

UserService->代理对象->代理对象.target=普通对象->依赖注入
代理对象.test();

class UserServiceProxy extend UserService{

  UserService target;
  
  //执行切面的方法(@Before)
    public void test(){
       target.test(); 
  }
}
@Aspect
@Component
public class TestAspect {

	@Pointcut("execution(public void com.test.service.UserService.test())")
	public void a(){

	}
	@Before("a()")
	public void testBefore(JoinPoint joinPoint) {
		System.out.println("testBefore");
	}
	
}

代理对象target的赋值:直接将UserService直接赋值给它:


生命周期流程spring如何判断bean对象是否需要进行初始化后的aop

@Aspect
@Component
public class TestAspect {

	@Pointcut("execution(public void com.test.service.UserService.test())")
	public void a(){

	}
	@Before("a()")
	public void testBefore(JoinPoint joinPoint) {
		System.out.println("testBefore");
	}
}

      切面也作为一个bean注入到spring容器中,spring会找出所有的切面bean(@Aspect),遍历每一个切面bean的方法,判断注解上的定义的表达式的和正在创建的bean对象是否匹配,若匹配,则将那些匹配的所有方法缓存起来map,在代理对象target执行test()方法之前的切面增强方法时,时从缓存取出相对于的方法,进行执行。

标签:初始化,生命周期,对象,创建,bean,UserService,方法,public
From: https://www.cnblogs.com/huang580256/p/16859331.html

相关文章