Spring 依赖注入后行为实现

发布时间:2020-07-20 23:04:12 作者:沙漏半杯
来源:网络 阅读:406

主要有两种方式:


1.通过实现InitializingBean接口的afterPropertiesSet()方法,在方法中处理业务


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


实现方式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.两种方式的区别:

实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖

4.注意:如果在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init- method,

 * 系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法



5.InitializingBean和init-mthod同时执行的原理:


详见: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 {

            //获取当前bean是否实现了InitializingMyBean接口,如果实现了就执行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 {

//调用afterPropertiesSet()

((InitializingBean) bean).afterPropertiesSet();

return null;

}

}, getAccessControlContext());

}

catch (PrivilegedActionException pae) {

throw pae.getException();

}

}

else {

//调用afterPropertiesSet()

((InitializingBean) bean).afterPropertiesSet();

}

}

            //如果在配置文件中设置了init-mthod属性就通过反射调用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();

}

}

}


推荐阅读:
  1. Java程序员必须掌握的Spring依赖管理原理
  2. Spring基本介绍,控制反转IOC与面向切面编程AOP

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java spring 互联网

上一篇:Redis学习笔记(一):Redis常用数据类型之string、hash和list的命令

下一篇:Fiewalld防火墙基础(一)

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》