Spring 依赖注入后行为实现

本文深入探讨了Spring框架中初始化bean的两种常见方式:通过实现InitializingBean接口的afterPropertiesSet()方法和配置init-method属性。详细解释了两者之间的区别,包括效率对比和对Spring依赖的消除,并提供了具体的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要有两种方式:

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.ch4.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();
				}
			}
		}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值