溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring 依賴注入后行為實(shí)現(xiàn)

發(fā)布時(shí)間:2020-07-20 23:04:12 來源:網(wǎng)絡(luò) 閱讀:406 作者:沙漏半杯 欄目:編程語言

主要有兩種方式:


1.通過實(shí)現(xiàn)InitializingBean接口的afterPropertiesSet()方法,在方法中處理業(yè)務(wù)


2.在配置文件中配置init-method


實(shí)現(xiàn)方式1:InitializingBean


<strong>@Component

public class InitializingMyBean implements InitializingBean {

? ? @Autowired

private UserRepository userRepository;

@Override

public void afterPropertiesSet() throws Exception {

System.out.println("》》》新增用戶《《《 ");

User user =new User();

user.setName("admin");

user.setPassword("admin123");

user.setAge("23");

user.setSex("男");

User add? = userRepository.save(user);

if(!StringUtils.isEmpty(add)){

System.out.println("新增用戶成功!");

}else{

System.out.println("新增用戶失??!");

}

}

?

?

}

</strong>

2.配置文件 :init-method

xml version="1.0" encoding="UTF-8"?>DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean name="lifeBean" class="research.spring.beanfactory.ch5.LifeCycleBean"

?init-method="init">bean>beans>


3.兩種方式的區(qū)別:

實(shí)現(xiàn)InitializingBean接口是直接調(diào)用afterPropertiesSet方法,比通過反射調(diào)用init-method指定的方法效率相對(duì)來說要高點(diǎn)。但是init-method方式消除了對(duì)spring的依賴

4.注意:如果在spring初始化bean的時(shí)候,如果該bean是實(shí)現(xiàn)了InitializingBean接口,并且同時(shí)在配置文件中指定了init- method,

?* 系統(tǒng)則是先調(diào)用afterPropertiesSet方法,然后在調(diào)用init-method中指定的方法



5.InitializingBean和init-mthod同時(shí)執(zhí)行的原理:


詳見:org.springframework.beans.factory.support包下的抽象類AbstractAutowireCapableBeanFactory


主要處理代碼如下:



/**

* Give a bean a chance to react now all its properties are set,

* and a chance to know about its owning bean factory (this object).

* This means checking whether the bean implements InitializingBean or defines

* a custom init method, and invoking the necessary callback(s) if it does.

* @param beanName the bean name in the factory (for debugging purposes)

* @param bean the new bean instance we may need to initialize

* @param mbd the merged bean definition that the bean was created with

* (can also be {@code null}, if given an existing bean instance)

* @throws Throwable if thrown by init methods or by the invocation process

* @see #invokeCustomInitMethod

*/

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)

throws Throwable {

? ? ? ? ? ? //獲取當(dāng)前bean是否實(shí)現(xiàn)了InitializingMyBean接口,如果實(shí)現(xiàn)了就執(zhí)行afterPropertiesSet方法

boolean isInitializingBean = (bean instanceof InitializingBean);

if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {

if (logger.isDebugEnabled()) {

logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");

}

if (System.getSecurityManager() != null) {

try {

AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {

@Override

public Object run() throws Exception {

//調(diào)用afterPropertiesSet()

((InitializingBean) bean).afterPropertiesSet();

return null;

}

}, getAccessControlContext());

}

catch (PrivilegedActionException pae) {

throw pae.getException();

}

}

else {

//調(diào)用afterPropertiesSet()

((InitializingBean) bean).afterPropertiesSet();

}

}

? ? ? ? ? ? //如果在配置文件中設(shè)置了init-mthod屬性就通過反射調(diào)用init-method指定的方法

if (mbd != null) {

String initMethodName = mbd.getInitMethodName();

if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&

!mbd.isExternallyManagedInitMethod(initMethodName)) {

invokeCustomInitMethod(beanName, bean, mbd);

}

}

}

/**

* Invoke the specified custom init method on the given bean.

* Called by invokeInitMethods.

* <p>Can be overridden in subclasses for custom resolution of init

* methods with arguments.

* @see #invokeInitMethods

*/

protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {

String initMethodName = mbd.getInitMethodName();

final Method initMethod = (mbd.isNonPublicAccessAllowed() ?

BeanUtils.findMethod(bean.getClass(), initMethodName) :

ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

if (initMethod == null) {

if (mbd.isEnforceInitMethod()) {

throw new BeanDefinitionValidationException("Couldn't find an init method named '" +

initMethodName + "' on bean with name '" + beanName + "'");

}

else {

if (logger.isDebugEnabled()) {

logger.debug("No default init method named '" + initMethodName +

"' found on bean with name '" + beanName + "'");

}

// Ignore non-existent default lifecycle methods.

return;

}

}

?

if (logger.isDebugEnabled()) {

logger.debug("Invoking init method? '" + initMethodName + "' on bean with name '" + beanName + "'");

}

?

if (System.getSecurityManager() != null) {

AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {

@Override

public Object run() throws Exception {

ReflectionUtils.makeAccessible(initMethod);

return null;

}

});

try {

AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {

@Override

public Object run() throws Exception {

initMethod.invoke(bean);

return null;

}

}, getAccessControlContext());

}

catch (PrivilegedActionException pae) {

InvocationTargetException ex = (InvocationTargetException) pae.getException();

throw ex.getTargetException();

}

}

else {

try {

ReflectionUtils.makeAccessible(initMethod);

initMethod.invoke(bean);

}

catch (InvocationTargetException ex) {

throw ex.getTargetException();

}

}

}


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI