六、Spring-准备BeanFactory

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

这里准备BeanFactory干了写什么?

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置beanFactory的classLoader为当前context的classLoader
		beanFactory.setBeanClassLoader(getClassLoader());
        //设置beanFactory的表达式语言处理器,spring 3增加了表达式语言的支持
        //默认可以使用#{bean.xxx}的形式来调用相关的属性
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
        //为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理一个工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
 
		// 添加BeanPostProcessor
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //设置了几个忽略自动装配的接口
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
 
		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
        //设置了几个自动装配的特殊规则
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);
 
		// Detect a LoadTimeWeaver and prepare for weaving, if found.
        //增加了对AspectJ的支持
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
 
		// Register default environment beans.
        //添加默认的系统环境bean
		if (!beanFactory.containsBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
 
		if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
 
		if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

下面选取其中几个方法说明一下。

1.特别的Aware接口

        // Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

     大家都知道在bean的生命周期中会调用一些Aware接口,但是这些接口是固定的几个,但是spring中实现Aware接口的接口 有好多,他们又是如何调用的?这里是使用BeanPostProcessor接口的postProcessBeforeInitialization方法实现回调的。

class ApplicationContextAwareProcessor implements BeanPostProcessor {
    @Override
	@Nullable
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
				bean instanceof ApplicationStartupAware)) {
			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}
}

bean生命周期调用的接口

	private void invokeAwareMethods(String beanName, Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

2.添加ApplicationListener侦测器

// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

      大家都知道在refresh方法中的registerListeners()已经添加到了容器中实现ApplicationListener接口的监听器,但是为什么为什么这里还要添加这样一个类?

ApplicationListenerDetector这个类干嘛的,大家看可以看看这个方法。

1、在Bean初始化完成之后:如果Bean是单例的则并且bean instanceof ApplicationListener。加入到this.applicationListeners中。

2、在Bean销毁之前搞事情: 如果Bean是一个ApplicationListener,则会从ApplicationEventMulticaster(事件广播器)中提前删除了。

class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {

@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		if (bean instanceof ApplicationListener) {
			// potentially not detected as a listener by getBeanNamesForType retrieval
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
				// singleton bean (top-level or inner): register on the fly
				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
			}
			else if (Boolean.FALSE.equals(flag)) {
				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
					// inner bean with other scope - can't reliably process events
					logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
							"but is not reachable for event multicasting by its containing ApplicationContext " +
							"because it does not have singleton scope. Only top-level listener beans are allowed " +
							"to be of non-singleton scope.");
				}
				this.singletonNames.remove(beanName);
			}
		}
		return bean;
	}
public void postProcessBeforeDestruction(Object bean, String beanName) {
		if (bean instanceof ApplicationListener) {
			try {
				ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
				multicaster.removeApplicationListener((ApplicationListener<?>) bean);
				multicaster.removeApplicationListenerBean(beanName);
			}
			catch (IllegalStateException ex) {
				// ApplicationEventMulticaster not initialized yet - no need to remove a listener
			}
		}
	}
}

3.增加了对AspectJ的支持

/ Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

aop概念

Aspect切面:一个分布在应用程序中多个位置的标准代码/功能,通常与实际的业务逻辑(例如事务管理)不同。 每个切面都侧重于一个特定的横切功能。
Joinpoint连接点:这是程序执行中的特定点,如方法执行,构调用造函数或字段赋值等。
Advice通知:在一个连接点中,切面采取的行动
Pointcut切点:一个匹配连接点的正则表达式。 每当任何连接点匹配一个切入点时,就执行与该切入点相关联的指定通知。
Weaving织入:链接切面和目标对象来创建一个通知对象的过程。

它使用来做代理的,大家都直到Java最流行的AOP框架:Spring AOP 和 AspectJ。

Spring AOP旨在通过Spring IoC提供一个简单的AOP实现,以解决编码人员面临的最常出现的问题。这并不是完整的AOP解决方案,它只能用于Spring容器管理的beans。

另一方面,AspectJ是最原始的AOP实现技术,提供了玩这个的AOP解决方案。AspectJ更为健壮,相对于Spring AOP也显得更为复杂。值得注意的是,AspectJ能够被应用于所有的领域对象。

AspectJ的aop代理 

AspectJ使用的是编译期和类加载时进行织入。

AspectJ使用了三种不同类型的织入:

编译时织入:AspectJ编译器同时加载我们切面的源代码和我们的应用程序,并生成一个织入后的类文件作为输出。
编译后织入:这就是所熟悉的二进制织入。它被用来编织现有的类文件和JAR文件与我们的切面。
加载时织入:这和之前的二进制编织完全一样,所不同的是织入会被延后,直到类加载器将类加载到JVM。

spring的aop代理 

运行时织入,在使用目标对象的代理执行应用程序时,编译这些切面(使用JDK动态代理或者CGLIB代理)。 

性能 

考虑到性能问题,编译时织入比运行时织入快很多。Spring AOP是基于代理的框架,因此应用运行时会有目标类的代理对象生成。另外,每个切面还有一些方法调用,这会对性能造成影响。

AspectJ不同于Spring AOP,是在应用执行前织入切面到代码中,没有额外的运行时开销。

由于以上原因,AspectJ经过测试大概8到35倍快于Spring AOP。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值