spring生命周期

spring的生命周期
@Component
public class UserService implements InitializingBean {
@Autowired
private OrderService orderService;
private User defaultUser;
public void test(){
System.out.println(“xxxx”);
}
@Override
public void afterPropertiesSet() throws Exception {
//mysql操作得到值,赋予defaultUser
defaultUser=new User();
}
@PostConstruct
public void chushihua()throws Exception{
//mysql操作得到defaultUser的值
defaultUser=new User();
}
}

1、通过类中的构造方法实例化生成一个对象UserService ,这个对象此时此刻的orderService没有值;
public UserService(){}
@Autowired
public UserService(OrderService orderService){}
如果有两个构造方法,默认会执行无参构造方法。如果给构造方法加上 @Autowired,那么就会使用该构造方法
public UserService(OrderService orderService){}
public UserService(OrderService orderService,OrderService orderService){}
当有两个都是有参的构造方法,并且没有无参构造方法的时候,spring就会报错,如果只有一个有参构造方法是不会报错的。
public UserService(OrderService orderService){}
默认先按照OrderService的类型去spring中去找,可能会找到多个,如果找到多个,那么再根据名字去找。名字是唯一的,不能重复的。(在单例池中允许同种类型,不同名字的类多次注入)。如果根据类型找到多个,再根据名字找不到入参的话是会报错的。
这就是推断构造方法;
2、属性填充,从spring内部拿到orderService的值,填充到UserService中;
@Autowired
@Autowired
private OrderService orderService;
@Autowired
private void a(OrderService orderService){
orderService=orderService;}
简单理解:根据OrderService类型去找,如果找到一个就直接用,如果多个就去找名字,以上两种都是可以用的。
统一被称为注入点,方法注入点,属性注入点。
属性赋值:如果找到多个,先判断该单例的属性autowireCandidate是否为true(默认为true,可以配置成false)
在这里插入图片描述
如果为false,那么将会被排除掉;
如果我们有三个不通名字的OrderService在单例池中
当我们改成orderService2去找后,直接就报错了。
@Autowired
private OrderService orderService2;
如果我们把其中两个autowireCandidate设置为fasle,只剩下一个的话,即使名字对不上也不会报错。
@Autowired
@Qualifier(“xxxx”)
private OrderService orderService2;
@Bean
@Qualifier(“xxxx”)
public OrderService orderService2(){
return new OrderService();
}
也可以这样配置,直接根据xxxx名字找。
@Bean
@Primary
public OrderService orderService2(){
return new OrderService();
}
加上 @Primary,主bean,就直接使用这个了。
如果以上都没有,才会根据属性的名字去找,中间有很多步骤。
@Resource
①、如果Resource注解指定了name属性,就直接从spring容器拿对应的bean,如果不存在则表示没有找到注入对象
@Resource(name=“xxx”)
private OrderService orderService3; 直接根据xxx找,找不到就报错。
②、如果Resource注解没有指定name属性,但是根据属性名字或setXXX中的XXX在spring容器中有对应的Bean,那也直接根据名字拿。
@Resource
private OrderService orderService3;
根据orderService3去看有没有对应的名字,如果不存在,根据类型去找,如果只找到一个没有问题,如果找到多个就会报错。
3、初始化
defaultUser没有注入到spring容器中,我们只是希望defaultUser有一个默认的值;比如我们需要从数据库查找一个值,然后赋予给他。
实现:让UserService 继承InitializingBean接口,实现afterPropertiesSet,就可以让我们程序员自由的操作了。给我们的defaultUser赋值操作,这就是初始化;或者使用 @PostConstruct注解不实现InitializingBean接口,也可以完成初始化,效果是一样的。
4、AOP

AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(“AppConfig”);
UserService userService=applicationContext.getBean(“userService”,UserService.class);
userService.test();
在这里插入图片描述
我们把userService的test方法作为aop的切点方法,执行到 userService.test();这一步后orderService为null;
当我们初始化完毕后,会去判断类是否需要执行AOP操作,去spring容器中把切面的bean拿出来,把切面的bean的注解拿出来看看当前类是否有匹配的AOP切点。我们这边是如果没有接口们就会由CGLIB去生成一个子类继承userServicede
比如:
class UserServiceProxy extend UserService{
private UserService target;
public void test(){
}
}
UserServiceProxy就是我们的代理类,这个target就是之前我们实例化的对象,并且这个target中的orederServcie是有值的。
在这里插入图片描述
当我们执行代理对象的test方法的时候,执行代理逻辑,再执行target.test()方法;
public void test(){
//代理逻辑
target.test() }
5、把代理对象放到spring容器中(如果没有AOP就直接把对象放到spring容器中)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值