现在有这样一个情景~
不希望通过注入的方式来赋值给admin,而是通过数据库查到admin然后包装成user在赋值给admin
package com.gavin.service.impl;
import com.gavin.pojo.User;
import com.gavin.service.UserService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class UserServiceImpl implements UserService , InitializingBean {
//这里不希望注入admin,而是通过数据库查到admin然后包装成user在赋值给admin
private User admin;
@Qualifier
private User user;
@Autowired
public void setUser(User user) {
this.user = user;
}
@Override
public String demp() {
user.say();
return"从来也不其";
}
@PostConstruct
public void init(){
User user = new User("李四", 23);
System.out.println("数据库查到"+user);
this.admin=user;
}
public User getAdmin() {
return admin;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("他是管理员");
}
}
这个就是代码的执行顺序问题,
初始化之前~
通过无参构造Constructor(构造方法)获得对象 -> 通过@Autowired(依赖注入) -> 注入之后通过反射查找到@PostConstruct注释的方法执行;
在初始化时,~判断是否是InitializingBean的实例执行invoke…检查权限,
执行afterPropertiesSet,否则直接强转为InitializingBean执行afterPropertiesSet.
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
在spring创建bean的时候触发,此时容器还未完全初始化完毕,如果逻辑中引用了还未完成初始化的bean会导致异常 ,所以需要考虑加载顺序。