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