spring 官方文档的接口理解整理(一)Bean

这儿提供一个我实验的源代码地址(有注释,如有错误,欢迎留言^_^,实验是检验真理的唯一标准):https://github.com/flycat0112/springArt

一、IOC容器

下面接口的执行顺序:BeanNameAware -> BeanClassLoaderAware ->  BeanFactoryAware -> applyBeanPostProcessorsBeforeInitialization -> invokeInitMethods -> applyBeanPostProcessorsAfterInitialization

/**
	 * Initialize the given bean instance, applying factory callbacks
	 * as well as init methods and bean post processors.
	 * <p>Called from {@link #createBean} for traditionally defined beans,
	 * and from {@link #initializeBean} for existing bean instances.
	 * @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 bean definition that the bean was created with
	 * (can also be {@code null}, if given an existing bean instance)
	 * @return the initialized bean instance (potentially wrapped)
	 * @see BeanNameAware
	 * @see BeanClassLoaderAware
	 * @see BeanFactoryAware
	 * @see #applyBeanPostProcessorsBeforeInitialization
	 * @see #invokeInitMethods
	 * @see #applyBeanPostProcessorsAfterInitialization
	 */
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

Ⅰ、自定义Bean的本质(对应项目的模块是spring-bean-lifecycle)

1、bean创建的时候做的操作(针对单个bean各自实现,不是所有bean):

org.springframework.beans.factory.InitializingBean   实现该接口,对bean创建之后做的操作。相等的注解:@PostConstruct

org.springframework.beans.factory.DisposableBean   实现该接口,对bean销毁前做的操作。相等的注解:@PreDestroy

ps:通过配置分别是init-method属性和destroy-method属性指定方法。设置默认的初始化方法和销毁方法可以通过配置中设置<Beans default-init-method="init"></Beans>这种形式。还有就是注解方式,通过实现接口方式,还有配置方式三种可以同时存在,他们的顺序是:先是注解,其次通过接口、最后是配置。

2、Bean的时间周期操作(针对所有单个Bean各自实现,但是,系统启动和结束才能调用,不受Bean的创建再次执行

org.springframework.context.Lifecycle    其中申明了三个方法start(), stop(),isRunning()三个方法。isRunning方法是决定stop方法是否执行,返回true会执行。

org.springframework.context.Phased    其中申明了一个getPhase方法,这个方法是为了控制bean的初始化顺序和销毁的顺序,返回数字小的先初始化。通过Collections.sort(keys)来排序,进而控制执行顺序的。

org.springframework.context.SmartLifecycle    该加接口实现了Lifecycle和phased接口,宁外新加了isAutoStartup(), stop(Runnable run)两个方法。第一个方法如果返回true,spring容器刷新的时候就会执行start方法;第二个方法和Lifecycle不同提供run是因为提供一个有序地或者并发(多线程)的支持

ps:上面的处理机制大概是这样,Lifecycle接口中stop方法是不会使用的,通常使用的SmartLifecycle接口额stop方法,这个处理机制只是org.springframework.context.LifecycleProcessor接口的默认实现org.springframework.context.support.DefaultLifecycleProcessor的实现机制。

3、LifecycleProcessor

org.springframework.context.LifecycleProcessor接口提供给ApplicationContext回调方法来刷新和关闭上下文(通过简单的委托的方式)

Ⅱ、Aware(对应项目的模块是spring-bean-aware)

org.springframework.context.ApplicationContextAware   中有setApplicationContext方法返回应用中当强使用的ApplicationContext接口的实现类。从其中获取查找我们想要的对象,写自己的方法,通过反射和业务代码解偶。

org.springframework.beans.factory.BeanNameAware  中有setBeanName方法返回当前实现的对象用key-value形式保存的spring容器中对应的key值。

ps:提供用户感知spring内部的对象。比如ApplicationContextAware提供ApplicationContext对象,BeanNameAware提供对象知道在spring容器里面保存对象的Key值(name)。spring-bena-aware的demo采用了应用实例,想通过委托的方式,方便地调用加密算法。

Ⅲ、容器拓展点(对应的模块spring-bean-expend)

org.springframework.beans.factory.config.BeanPostProcessor接口提供方法有postProcessBeforeInitialization,postProcessAfterInitialization两个。他们做操作是针对所有容器中的对象,不是只是针对本对象。ps: before方法在@PostConstruct、InitializingBean接口、init-method的对象执行之前,after在之后。源码调用情况查看开头源代码。

org.springframework.beans.factory.config.BeanFactoryPostProcessor 接口提供postProcessBeanFactory方法,针对创建Bean之前,只存在创建bean的配置文件,该接口可以对创建bean的参数进行修改,比如,对spring的jdbc配置里面使用参数(properties)文件,需要把值${}替换成参数文件里面对应的值,不能设置bean标签的属性,因为调用该对象前那个对象已经创建了。

org.springframework.beans.factory.FactoryBean接口提供一个创建Bean对象的工厂,方法有getObject,getObjectType,isSingleton。通过java代码创建复杂对象放到容器中。从容器中获取该对象只能通过“class”或者“注解”的方式从spring容器中获取对象,不能通过对象名称获取对象。

Ⅳ、spring注解(对应项目的模块是spring-bean-anntation)

@Required   设置set方法参数是否可以为null

@Primary   提升优先级

@Configuration 作用和@Component注解相同,但是@Configuration一般和@Bean一起用。

@Bean 功能和实现org.springframework.beans.factory.FactoryBean接口相似

@Autowired @Qualifier     确定详细的对象,@Autowired注解和@Resource注解的区别是,它要确定那个对象需要和@Qualifier来确定,并且,没有@Qualifier的话,默认通过类型来查找。

@Resource    默认通过变量名称来查找,如果变量是bean3,这儿找不到对象,报错。

@Scop   设置是单例,多例等

@DependsOn  设置bean的创建顺序。

ps:可以定义自己的基于@Qualifier注解作用相似的注解,用来详细确认一个对象来注入,可以自己定义其余的属性来确认。
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值