赞
踩
这个你看源码是没有@Compent注解的,但是@Configuration是有的,所以,你这个@ComponentScan必须至少想一个让spring扫描你这个类的办法。
ImportSelector和ImportBeanDefinitionRegistrar都可以,前者是返回一个数组,全类名的,后者则是直接往BeanDefinitionRegistrar里面注册bean,难度有点大,其实一般情况下,我们直接导入类就可以了。
这个和BeanFactory不同,这个是注册bean,那个是获取bean,简单说一些问题,如果你单单查看容器中的组件,那么它就会是这个工厂,但是你如果通过这个工厂的id来拿bean的时候,获取到的就是调用getObject方法得到的实例。
那如果我就像获取这个工厂呢,不知道你还记得你在看源码的时候看到过&
前缀符,没错!只要你在id前面加一个&前缀就可以实现直接获取这个工厂bean了。
另外我再说一下,可能是在使用的时候,对new 一个对象比较敏感,但是你要清楚,spring底层的原理也是new对象,而且你一旦把对象放进容器里面,那赋值什么的,更不就不是你需要考虑的事情。
这个里面可以指定bean的创建和销毁方法,但是我还是喜欢用注解。
同时注意一点,如果是被bean标注的方法互相调用的话会发生什么呢?答案是它会从容器中获取,而不是执行那个方法,首先你看,你写的那个类没有实现任何有关的接口,所以互相调用的时候,肯定不是jdk的代理,不是jdk代理的话,方法之间的互相调用就是有spring加强的调用。
而一个配置类,你创建的bean互相调用是很正常的,所以你要理解这样做是可以的
可以写基本的值
可以使用SpEL#{}表达式,这个我学的时候好像跳了,等最近几篇博客补一下
可以写${}取环境变量中的值
SpEL
真的是非常的强大,比如它可以直接注入一个组件#{组件id},你说没用?等我试一试静态的组件。
好吧,还真是不能,而且还有一个大坑,就是它启动不会报错,不过幸好idea提示我们不能那样做了。
然后是我认为一个有用的点,#{组件id.属性},有的时候,我们经常需要获取一个复杂对象的值,比如配置类,但是依据单一职责,我们这个类肯定只需要获取这个配置类的一部分,总不能每次在方法中获取吧,当然,你通过方法注入也是一种办法,但是还有更优雅的,就是使用value,经过测试是支持静态变量或者常量的,普通的那更不用说,而且idea是会有提示的
#{组件id.方法}得到的是这个方法的返回值,而且可以处理null的情况,比如testConstant.showProperty()?.toUpperCase(),代表testConstant.showProperty()结果为null的话后面的就不执行。而且是可以传递参数的
#{T(类全路径).方法名}为什么我这里写的是方法名,因为你写属性完全没有意义的,还不如直接给属性赋值,但是你像方法名。。。好像也可以直接使用唉。。
可以进行逻辑运算,逻辑运算符使用的是Python那套and,or,not,三元自然也是没问题
正则表达式,#{字符串 match ‘正则表达式’}
对list或map的取值,好家伙,这就是语法层面模仿Python啊
还有集合筛选语法,挺高端的,我直接把别人的博客贴上来了,就不总结了
public class TestSpringEL {
/*
* 声明City类,有population属性 testContants拥有名叫cityList的City类List集合
*/
// 过滤testConstant中cityList集合population属性大于1000的全部数据注入到本属性
@Value("#{testConstant.cityList.?[population > 1000]}")
private List<City> cityList;
// 过滤testConstant中cityList集合population属性等于1000的第一条数据注入到本属性
@Value("#{testConstant.cityList.^[population == 1000]}")
private City city;
// 过滤testConstant中cityList集合population属性小于1000的最后一条数据注入到本属性
@Value("#{testConstant.cityList.$[population < 1000]}")
private City city2;
/*
* 首先为city增加name属性,代表城市的名称
*/
/*
* 假如我们在过滤城市集合后只想保留城市的名称,
* 可以使用如下方式进行投影
*/
@Value("#{testConstant.cityList.?[population > 1000].![name]}")
private List<String> cityName;
}
SpelExpressionParser
是执行这些都核心类,感兴趣的可以看一下
可以加载外部配置文件的值到环境变量中,然后通过@Value的方式读取${}
比如多数据源,肯定有一个是主要的数据源,我们不想在每次注入的时候指定,所以就在组件上加这个注解,如果你是bean的话就加在方法上,还有一个应用场景,比如旧的项目要使用新的数据源,你就直接给旧数据源设置@Primary,就不需要改以前的代码了,但是呢这个只对@Autowired起作用,所以我优先推荐使用这个注解,准没有错!!!
AutowiredAnnotationBeanPostProcessor负责了这个注解功能的实现。
任何给定 bean 类中只有一个构造函数可以声明此注释,并将 ‘required’ 属性设置为true ,指示构造函数在用作 Spring bean 时自动装配。此外,如果 ‘required’ 属性设置为true ,则只能使用@Autowired注释单个构造函数。如果多个非必需的构造函数声明了注解,它们将被视为自动装配的候选者。将选择在 Spring 容器中通过匹配 bean 可以满足的依赖项数量最多的构造函数。如果不能满足任何候选者,则将使用主/默认构造函数(如果存在)。如果一个类只声明了一个构造函数,即使没有注释,它也会一直被使用。
它在构造器注入,方法注入,参数注入等都不要求是public,所以,为了封装性,我们最好选择私有private,关于构造器和方法这个,你甚至都可以标注在方法的参数上面,可能是为了说明可有可无吧,毕竟有required属性。而且方法注入的时候,你是可以利用容器的,没有必要手动从容器中获取bean了
populateBean
这个是在我们说看到的所有的bean的接口前面执行的,这个的目的是给bean的属性赋值,也就说!你在使用后面任意一个接口的时候,bean的自动输入的属性都是可以操作的。
直接说核心,这个方法会在一个bean创建完毕并且属性已经被注入以后执行,也就是说,我们可以使用bean中的其他组件。
没得说,销毁之前执行
这个是针对所有bean的,postProcessBeforeInitialization在一切初始化方法之前,postProcessAfterInitialization在一切初始化方法之后(这个和销毁无关),你可以理解为对bean的一种aop,
浅看下源码吧!
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
//spring用这样的方法实现了bean的层层加工,具体的思路就是利用result保存返回的结果,并且循环的放入参数中使用,这个方法避免了递归,而且你看如果你返回的对象是null,那么就不会再传递给其他方法了,所以大部分情况下,你都不需要担心null的问题
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
下面是整体的逻辑,我们还注意到,如果这个bean是合成的,那这个接口是不起作用的
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
//这个是先执行接口定义的方法,然后执行bean定义的方法,而且如果我猜的没错的话,如果你的方法是private的话,它也是会执行的,因为spring可能已经想到,不想让人在使用这个类的时候,再执行这个初始化方法了
}
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);
}
你所熟知的参数校验就是它完成的,所以,为什么它可以负责那么多地方的参数校验,也不稀奇了吧?看来自己的校验框架和spring的差别挺大的,包括自己的权限框架,这些从原理上来看,和spring的就大有不同。
而且让你的@PostConstruct也是这样的执行的原理,只能说,只是我暂时想不到用处,其实用处多了去了。
而且而且,核心的Autowired也是通过这个方法来实现注入的,唉,等等你不是说这个时候属性都已经弄好了吗?对呀,你的接口肯定是要放在这个后面执行的呀,哦哦,这下通了。
我直接给你一个总结吧,你能看到的,在bean的所有可以起作用的注解,十有八九都是利用这个实现的!当然,如果这个传递的参数更复杂就好了,不过呢,一个object给了我们之后,理论上只要是相关的,都可以通过反射获取!
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);
}
}
}
而且这个接口是真的恐怖,你看一下它的子接口,多的数不完,如果你想实现那种获取和自身绑定的属性,说不定看看Aware就有呢。
那具体是怎么实现的呢,这个时候明明规范的重要性就来了,比如你xxxAware就是用xxxProcessor来具体实现的
我在写框架的时候,经常要用到ApplicationContext,但是我以前的做法是注入这个组件,不过这个接口明显就更专业了,而且有很多环境肯定不是你能注入进去的
这个接口可以负责解析spring中几乎全部的字符串,包括#{}和${}甚至你看继承树,连时间cron都是由这个类的子类去解析的,这样我详细你对spring框架也不会再感到神秘了吧。
这个和环境有关,具体来看的话,就是什么dev,prod,test环境,你可以设置环境,而且最关键的是,设置完成后你要刷新整个ioc容器,refresh,现在你知道为什么ioc容器需要refresh了吧。
joinpoint必须要放在参数列表的第一位
EnableAspectJAutoProxy
开启aop,这种注解的原理一般就是导入了某些类,就和自动装配一样。不过目前我没有用这个也是可以进行aop的,所以我们重点看import的AspectJAutoProxyRegistrar
这个类实现了我们眼熟的ImportBeanDefinitionRegistrar,它应该是要自己注册bean吧,这样aop和ioc难道可以联系起来吗?
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//如果没有就注册一个新的进去
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//这个我们的注解属性进行判断,执行相应的操作
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
这个是上面那个类在容器中注册进去的一个组件,而且也提供了一些思路,研究框架的时候,入手点是什么,处理自动配置引入的关键类,log,debug,栈还有这个enablexx,我觉得yaml也是一个突破口,所以研究一个框架的思路你有了,剩下的不就是方法吗,不过在此之前,一定一定要学会怎么使用它。
有思路了,就是通过类继承器,你要注意,idea那个是可以调整结构的,寻找核心的接口,比如我就找到了BeanPostProcessor,看看能不能从这里突破。看的时候肯定是要从顶层开始突破的,关注重要的方法,尤其是关注子类重写的重要的方法,不然你从下往上看,有很多方法多多少少都会有点迷糊。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//获取名称,不用多说
//注册一个检查的,如果一个bean不符合所有的BeanPostProcessor
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//分类,spring说这是有意义的,为了保证顺序,你不能重构它
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//priority是指高优先级的
//internal是指内部的
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//很明显这个判断逻辑会让这个pp重复出现在两个列表中,比如AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//排序priority并且注册
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//排序order接口并且注册
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//我在想,这种需要排序的,难道不是使用一种数据结构更好吗
// 注册其他没有标注这些的BeanPostProcessor
//到这里我顿悟了,只要我不去使用PriorityOrder接口,就不用担心和spring的产生冲突,其实你看PriorityOrder什么都没有定义,但是spring用这个巧妙的把这个分开了。
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 重新注册所有内部 BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//重新注册用于将内部 bean 检测为 ApplicationListeners 的后处理器,将其移动到处理器链的末尾(用于拾取代理等)。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
那中间还有一个很关键的过程,就是创建bean,那个是怎么做到的呢?我们看源码
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);//这个里面涉及到了&工厂前缀的转换,应该是转化为实际的名字
Object beanInstance;
// 看看我们能不能直接获取到这个bean,这个里面就有解决循环依赖的三级缓存map!感觉很多地方都慢慢的联系起来了
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//这个好像和beanFactory有点关系
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//下面是判断是否有循环引用的核心方法,所以你不用担心循环应用,如果真的出现了,而且spring没有解决的话,他是会直接报错的!
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//下面很明显是在工厂中判断,而且是那种递归的,找不到就看看父工厂有没有,我就不翻译了,不过还是学一个新单词,delegate 代表 ,比如在if语句中,我也喜欢用这种假设来帮助编码
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 保证当前 bean 所依赖的 bean 的初始化。
String[] dependsOn = mbd.getDependsOn();//获取依赖
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {//分析循环依赖
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 创建bean实例
if (mbd.isSingleton()) {//单例
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//输错了不要担心,spring会提示你的
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
总之现在的结果是我们创建了这个BeanPostProcessor,后续再创建的时候,都会被这个拦截住,上次我们是看到了这里,现在我对这个流程已经比以前清楚多了,现在我整理一下前面忘记的或者没有理解的,然后接着往下看AOP
首先,@EnableAspectJAutoProxy给容器中注册了AnnotationAwareAspectJAutoProxyCreator。
额外记录一个GenericTypeResolver,是spring针对泛型的工具类,我为什么找这个呢,因为我想实现在返回消息封装体之前,包装那个类,现在有能力,分析源码找找解决方案。
之前往容器里面注册了internalAutoProxyCreator,这个实现了BeanPostProcessor接口,实际实现的类是AnnotationAwareAspectJAutoProxyCreator
在bean创建的过程中,先是获取了BeanFactoryAware,然后一路传递下来调用initBeanFactory
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
//反射通知工厂
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);//这个相当于把工厂和上面创建的对象重新包装了一下
}
这个就相当于注册,然后关键的就是它是怎么拦截我们的bean并且执行的呢?简单猜测,这肯定是要自己写一个值解析器,然后解析aop表达式是不是匹配上这个类中的方法,然后使用代理,创建新的对象,并且放到容器中。当然这只是一个猜测!
AbstractAutoProxyCreator这个应该是一个代理类的创建者,里面也是有map缓存的,这个实现了BeanPostProcessor对bean做了全局的拦截。
不知道你是否记得,我们在创建bean实例之前,有过一次获取代理对象的尝试,而aop肯定是通过代理实现的,所以这两者就联系起来了。InstantiationAwareBeanPostProcessor接口先进行代理处理,你记住,这个是获取bean实例,也就是说,和后面注入依赖的时候完全是两码事情,如果你没有返回代理对象,都后面返回的也就是一个普通的空对象而已。然后两者殊途同归都会被之后的BeanPostProcessor处理的!
那怎么代理呢?
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {//advisedBeans保存了所有需要增强的bean
return null;
}
//Advice,Pointcut,Advisor,AopInfrastructureBean接口和使用@Aspect都属于这个
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);//直接放进了需要增强的缓存里面
return null;
//我感觉这个只有切面本身或跳过去返回null吧,我们看看这个map里面保存了什么,好家伙还真不少呢
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {//这个是有事物的切面类,然后就是我们自己定义的切面了,我们发现这个保存的信息非常的详细,这样的话,我们把这个信息保存在一个类里面,也不修改接口的时候,岂不是也可以增加方法的参数了!!!这是一个很大的收获啊
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
说实话,上面那个看的我云里雾里的,那个方法肯定是会返回null的呀,而且只是把那些需要增强的放到了一个map里面,然后呢,我们看看下面的吧,不知道能不能连上去
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {//这个判断有点意思啊,都让我打算去好好温习一遍集合了,不过我感觉应该先看多线程再学集合,因为集合涉及到多线程,但是集合基本使用简单啊
return wrapIfNecessary(bean, beanName, cacheKey);//这个就一个核心方法
}
}
return bean;
}
看看这么包装这个bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 首先获取了所有的aop增强器,然后AopUtils.findAdvisorsThatCanApply获取应用的增强器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);//这个时候已经获取到了排序完成后的增强器
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//这个明显是核心中的核心啊
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
核心匹配方法
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);//获得所有的方法
for (Method method : methods) {//遍历方法,并且看看是不是匹配这个方法,所以spring的aop是针对方法而言的
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
//AspectJExpressionPointcut我找到了这个核心的匹配器,当然这个逻辑我就不关心了,idea足够帮助我们判断切住哪些了
return true;
}
}
}
创建代理对象
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();//代理工厂出现!
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//设置增强器和目标类,唉,我感觉这才是实际上的工厂,我给你材料,你给我装配
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
//customize:定制
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);//核心方法在这里
}
中间那些get方法我跳了,下面直接上重点!
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);//jdk动态代理
}
return new ObjenesisCglibAopProxy(config);//cglib动态代理
}
else {
return new JdkDynamicAopProxy(config);//jdk动态代理
}
}
这个判断总结起来就是,如果我们没有强制Cglib,而且是以接口实现的,那么优先使用jdk动态代理,jdk是通过实现接口的,所以内部调用内部方法由于this的原因,代理不生效,然后Cglib是通过继承实现的,互相调用是有代理的,这就是事务的大要点!但是spring还是推荐我们使用jdk,所以,才到处都有接口注入
CglibAopProxy是一个类,一顿操作后就得到了我们的代理对象,确实牛逼,确实是运行是产生的,牛逼牛逼
不管是以什么方法产生的,最后都会把容器中的bean替换成我们的代理对象
然后我们研究一下,这个代理对象在执行方法的时候会是什么样的呢?我一点进入方法,没有进入原来的方法,而是直接进入了代理对象的方法,我们来看看
CglibAopProxy
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//下面这些其实就是遍历所有的增强器,然后把他们转换成interceptor保存到interceptorList里面
List<Object> chain =
this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);//获取调用链,这个就很明显了,你看spring在做了非常多的注释,我们来好好看看
Object retVal;
// 检查我们是否只有一个 InvokerInterceptor:也就是说,没有真正的建议,而只是对目标的反射调用。
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 我们可以跳过创建 MethodInvocation:直接调用目标。请注意,最终调用者必须是 InvokerInterceptor,因此我们知道它只对目标执行反射操作,并且没有热交换或花哨的代理。
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 如果有拦截器链的话,你看它几乎把所有的东西都放进来这个对象中,然后执行proceed,这个就和我们定义环绕切面一样
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
//创建的源码告诉你,非public不代理,object对象也不会代理,然后object对象的什么equal,hash,toString这种方法也不会代理,这可不是你看代理失效场景能看出来的
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
怎么转换成Interceptor
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {//这个适配器其实就是Before,afterReturning,Throws等等,通过适配之后,返回并且添加到里面
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
其实你想想,无论是多么复杂,套了多少层,最后对于那个方法来说,肯定都是前面的一个一个执行,然后反过来后面的一个一个执行呀。
怎么执行方法?
ReflectiveMethodInvocation
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}//这个明显是没有拦截器才这样执行,而且你看里面最后也只是简单的method.invoke,不过我发现这个nterceptorsAndDynamicMethodMatchers是会变的,当执行到最后还是执行的实际方法
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//一个一个的获取拦截器,然后执行
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
//执行拦截器
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
//这个this就是CglibMethodInvocation
}
}
((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)
private static final ThreadLocal<MethodInvocation> invocation =
new NamedThreadLocal<>("Current AOP method invocation");
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();//你以调用这个,好,这就进入递归循环了
}
finally {
invocation.set(oldInvocation);
}
}
AspectJAfterThrowingAdvice
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {//这个用了catch,说明只有抛出异常才会执行
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
AfterReturningAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
//连try都没有,肯定是正常返回才会执行
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
AspectJAfterAdvice
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
//为什么它无论成败都会执行,就是因为这个
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
MethodBeforeAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
//就是为什么@before能够永远挨着目标方法前执行的原因
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
注意看我写的顺序,这就是aop实际执行的循环,先是利用前面的执行那个proceed方法,其实就是一个一个的往后面递归,基本没有做什么,然后执行到了@Before,它才做了一些正经的时候,然后又递归回去,你又不能保证只有你一个前置通知,然后正常方法开始执行,但是无论怎么执行,那个调用堆栈就已经形式了,spring利用了java自己的try-catch机制实现了这一切。
invokeBeanFactoryPostProcessors(beanFactory)调用在上下文中注册为 bean 的工厂处理器。
这个是继承了下面的接口,这个接口本身的方法,void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;是在下面那个接口前面执行的
调用时机:这个时候beanFactory已经被创建好了,但是bean还没有被实例化。核心处理流程和BeanPostProcessor是一样的,甚至警告都是一样的,哈哈
简单总结一下,两个接口有点类似因为有继承关系,而且上面执行下面接口的那部分代码是一样的。那我们看看spring是怎么用的,省得自己云里雾里的,好像是aop工厂用到这个方法,但是我不太熟悉这个,等回头写aop工厂的时候再说这个吧
监听事件,而且可以通过泛型指定监听什么事件,甚至你可以写ApplicationEvent监听所以的事件,我自己想象怎么实现这个,首先肯定是要得到所有的监听器,然后取出来,获取泛型,放到一个map<ApplicationEvent,List>里面,然后等事件发生的时候,我们去调用它,至于这个事件的发生,我暂时的猜测是使用java的发布订阅模式。
applicationContext.publishEvent,我们可以获取应用上下文,在任意时刻发布事件
拿refresh里面的最后一步finishRefresh(),AbstractApplicationContext,这个类是一个核心类,我们把它记录在这里,从550多行,开始我们的生命周期方法。
finishRefresh
里面有一个非常可爱的方法,idea给它带上了一个耳机。然后真正干活的是这个方法,看文档的意思应该是可以让多个事件监听器监听到getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType),当然我们这里考虑的仅仅只是容器成功事件。
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();//这里是想着获取异步执行器的
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {//没有的话,也得执行
invokeListener(listener, event);
}
}
}
上面这个你不用担心,因为自己发布的事件也是会走这个流程的。单从这点来看,我没想到用异步的方法执行,看多线程我还是学的不行,其实就没入门(
initApplicationEventMulticaster
这个可以是触发的核心方法,你看名字就能猜测出来了
protected void initApplicationEventMulticaster() {
//这个方法其实特别简单,你别看它写的复杂
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {//如果有我就从容器中获取
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {//如果没有,我就创建一个简单的,然后放到容器中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
registerListeners
上面是注册监听器,下面是注册监听器了,纠正一下,中间还有onRefresh()这个方法,虽然我不了解这个具体干了什么,但我能感觉出这个名字起的,它一定是一个核心的方法。
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
//这个注释的太好了,我终于明白了!!!我一直好奇,你监听器在派发器后面注册,那前面的事件怎么给监听器呢,原来是把以前的事件的保存起来了
//我在想一下,为什么不把监听器先注册呢,因为你的监听器要加到派发器里面,所以肯定是派发器先注册的,然后为了保证前面的事件也可以监听到,就使用了这样的办法。这种豁然开朗的感觉
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
监听事件的注解,和接口的效果是一样的,好家伙,这个原因和我想的一样啊,接口的方法是没有办法实现的重载的,就是那种泛型的重载,所以使用了这个注解,不得不说,比接口强大,盲猜是因为泛型擦除。
将方法标记为应用程序事件的侦听器的注释。
如果带注释的方法支持单个事件类型,则该方法可以声明一个反映要侦听的事件类型的参数。如果注解的方法支持多种事件类型,则该注解可以使用classes属性引用一个或多个受支持的事件类型。有关更多详细信息,请参阅classes javadoc。
事件可以是ApplicationEvent实例以及任意对象。
@EventListener注释的处理是通过内部EventListenerMethodProcessor bean 执行的,该 bean 在使用 Java 配置时自动注册或通过手动注册 或者 使用 XML 配置时的元素。
带注释的方法可能具有非void返回类型。当他们这样做时,方法调用的结果将作为新事件发送。如果返回类型是数组或集合,则每个元素都作为新的单独事件发送。
此注释可用作元注释以创建自定义组合注释。
异常处理
虽然事件侦听器可以声明它抛出任意异常类型,但从事件侦听器抛出的任何已检查异常都将包装在UndeclaredThrowableException中,因为事件发布者只能处理运行时异常。
异步侦听器
如果您希望特定侦听器异步处理事件,可以使用 Spring 的@Async支持,但在使用异步事件时请注意以下限制。
如果异步事件监听器抛出异常,它不会传播给调用者。有关更多详细信息,请参阅AsyncUncaughtExceptionHandler 。
异步事件侦听器方法不能通过返回值来发布后续事件。如果您需要发布另一个事件作为处理的结果,请注入一个ApplicationEventPublisher以手动发布该事件。
订购听众
还可以定义调用某个事件的侦听器的顺序。为此,请在此事件侦听器注释旁边添加 Spring 的通用@Order注释。
这个接口的方法在所有bean创建好后执行,问题,我也是一个bean,怎么保证所有bean创建好呢,看源码
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}//上面执行了bean的遍历保证所有的都创建好了
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {//下面又遍历了一次,把SmartInitializingSingleton类型的拿出来,怎么说呢,效果实现了,可是为什么不是在上一次遍历的时候,把这些放在一个list里面呢
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
我们有了前面的基础,对部分核心方法有了一定的了解,我们再来看一遍这个核心方法
刷新前的预处理
protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); //设置状态标志,统计时间 // 初始化自定义属性,这个是一个空方法,你可以利用子类去实现它,这个设计模式我也用过! initPropertySources(); // 这个会校验你刚刚定义的属性 getEnvironment().validateRequiredProperties(); //这个是事件监听者 if (this.earlyApplicationListeners == null) { //我debug的时候,走到了这个逻辑,那不用说,估计刷新的时候,就是走下一个逻辑,如果是这样的话,earlyApplicationListeners是不会消失的 this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);//里面有12个监听器呢 } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // 这个我们就知道了,是保存早期无法被送达的事件,你说这种东西不看两遍谁敢说理解? this.earlyApplicationEvents = new LinkedHashSet<>();}
总结:
设置的启动标识符,记录了启动时间,准备了系统早期监听器和早期事件保存list,因为那个时候,还没有创建出ioc
获取bean工程,obtain获取的意思,还是get顺眼,这个一下没看出来,哈哈
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {//这个就是刚刚那个原子性boolen了,不过不是刚刚那两个,你看这个方法的语意,或者更简单的,你看下面的异常:GenericApplicationContext 不支持多次刷新尝试:只需调用 'refresh' 一次,也就是说,我希望你这个变量false,如果是的话,我给你设置为null,这个可真是在一个对象中的原子性的操作,是不会有意外的,当然,如果你是true的,我就抛出异常,告诉你不能这样
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
//这个id就是你定义的application.name,记住对于spring来说,这个是id,我在做框架的时候才知道这个的
}
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;//这个很简单,关键是它从哪里来的呢?
//那个时候没有ioc是通过父类直接new对象,在refreshed之前就产生的org.springframework.beans.factory.support.DefaultListableBeanFactory
}
总结:很简单,就是获取bean工厂
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//用什么类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
//表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
//属性编辑器的注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 这个加了一个BeanPostProcessor,用来判断是不是实现了ApplicationContextAware接口,我感觉这个很简单,就看了一下源码,这种BeanPostProcessor的原理肯定都是先判断再执行的,不过是启动期间都做好了,那么bean一个一个进这个里面处理,怪不得启动速度会那么慢呢,不过都是小问题
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//下面的意思,你不能通过这些接口类型来实现@Autowired注入
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);
//下面和上面的相反,是可以自动注入的,原来这种特殊接口的注入原理不是ioc,不然ApplicationContext怎么保存它自己呢
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//将用于检测内部 bean 的早期后处理器注册为 ApplicationListener
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 下面是编译时的Aspectj支持,而我们现在都是动态代理,暂时不管这些
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()));
}
// 注册默认的环境组件
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
/** 我把上面的名称包括类型都贴在下面了,不然没法使用
environment:ConfigurableEnvironment,
systemProperties: Map<String,Object>,
systemEnvironment,Map<String,Object>,
applicationStartup:ApplicationStartup
*/
}
总结:为beanFactory这个工厂做了特别多的处理
开始准备进入try-catch包裹的和核心阶段
这默认是空方法,目的就是spring在处理完beanFactory之后,你也可以再处理一遍,但是我debug的时候,它进来了AnnotationConfigServletWebServerApplicationContext,一看就是和注解有关的,我们看看这实现了什么
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));//加了新的处理器beanFactory.ignoreDependencyInterface(ServletContextAware.class);//忽略了新的接口//明显这个两个都是和web上下文有关的
然后把beanFactory保存到了ExistingWebApplicationScopes,我也不懂是干什么的,然后其他的分支都没有执行
总结,留给用户对beanFactory再做进一步的处理
这个就是主要执行我们刚刚学习过的那和beanFactory有关的后置处理接口
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//如果有的话,首先调用 BeanDefinitionRegistryPostProcessors
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//先归类,然后放到了上面的两个集合里面
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
//不要在此处初始化 FactoryBeans:我们需要让所有常规 bean 保持未初始化状态,以便 bean 工厂后处理器应用到它们!将实现 PriorityOrdered、Ordered 和其余部分的 BeanDefinitionRegistryPostProcessor 分开。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判断分类存放
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//注册
registryProcessors.addAll(currentRegistryProcessors);
//执行
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//执行了有PriorityOrdered的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry
//清除
currentRegistryProcessors.clear();
//和上面的一样,代码我直接删了,目的就是分开PriorityOrdered和普通Ordered
//执行了有Ordered的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry
// 下面的其实也一样,执行了什么都没有的的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// 下面是执行BeanFactoryPostProcessor的postProcessBeanFactory,
//这个时候和BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry已经无关了,你注意看下面两个集合的元素是哪里来的就行
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//这个是来自上面的好多次添加,看来把所有的都包括了
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
//那这个就很明显了,就是直接实现BeanFactoryPostProcessor的了,看来这个的执行在人家的后面,这下就彻底清楚了
}
else {
// 这个肯定就是我没有实现BeanDefinitionRegistryPostProcessor,然后直接执行的BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//这次是直接获取BeanFactoryPostProcessor,然后执行
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
//以前执行过的就不执行,其实我感觉这里写continue更好一些
}
//人家下面还是先分类然后执行的
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//下面的都不需要我们去看了,不过总觉得这个算法的流程可以化简一点
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
上面的是通过排序后循环执行的,他们之间就是互相套起来的,把工厂一次一次的传入,一层一层的像流水线一样的处理。
总结,按顺序执行和工厂有关的接口方法。
至此工厂相关的全部处理完毕。
这个是我们最熟悉的BeanPostProcessor对bean创建的拦截,几乎所有对bean的赋能就是从这里开始的。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//这个就简单多了,只有一个接口,我着重看看不同的地方
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//把接口定义和一个用来做检查的都放到了以前bean工厂保存的BeanPostProcessor里面
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//开始分类
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//注意这里还有一个分类
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 这个是最后执行的,比没有实现order还靠后,从源码的形式看,这些都是实现了MergedBeanDefinitionPostProcessor接口的bean
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//你看下面这个逻辑,把找到的那个删除了,然后添加到了最后一个,效果就是把一个元素移动到最后。ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
if (beanFactory instanceof AbstractBeanFactory) {
//如果你的beanFactory是这种类型
// Bulk addition is more efficient against our CopyOnWriteArrayList there
((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);//直接塞进去
}
else {
for (BeanPostProcessor postProcessor : postProcessors) {
//遍历执行,你注意看传递参数给了factory,一个一个添加进去
beanFactory.addBeanPostProcessor(postProcessor);
}
}
}
总结一下,这个只是注册后置处理器,并没有执行呢
protected void initMessageSource() {
//这个简单,如果有对应的组件就获取没有就new一个,就像条件装配一样
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
总结,国际化相关的,你不需要太关心
和上面的很类似,不解释了
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
总结,获取一个事件派发器组件,基本原理是事件产生主动调用这个,然后这个根据事件的不同,去遍历调用监听器的方法,所谓的被动执行更不就是不可能的,肯定都是这种主动执行的原理,而且如果真的是那种定时监听执行的,那种情况也少,我之前写过相关的内容,比如redis承受量是7w/s那我主动每秒拉去6w保证高可用。
没想到这个是留给子类重写的空方法,但是我在mvc环境中进来了,我们看看执行了什么,注意一下,这个时候是工厂和事件监听都弄好了,但是bean还只是处于注册好的状态。
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
ServletWebServerFactory factory = getWebServerFactory();//核心方法应该是这一个
createWebServer.tag("factory", factory.getClass().toString());
this.webServer = factory.getWebServer(getSelfInitializer());
createWebServer.end();
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
protected ServletWebServerFactory getWebServerFactory() {
// Use bean names so that we don't consider the hierarchy
String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
if (beanNames.length == 0) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
+ "ServletWebServerFactory bean.");
}
if (beanNames.length > 1) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
}//上面这些判断说明有且只能有一个这样的组件
return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);//目测是一个ServletWebServer工厂,看了一下源码,工厂创建出的webServer就涉及到了容器的启动,等学习mvc的时候,我就大概知道这些来源了
}
总结,留给子类为在bean真正创建之前做准备,mvc在这里创建了服务器
protected void registerListeners() { // 系统监听器 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } //其他的listener String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } //注意上面只是把事件监听器注册到派发器里面了 //下面这是真正的把早期的事件派发出去 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (!CollectionUtils.isEmpty(earlyEventsToProcess)) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } }}
总结,把监听器发到派发器里面,并且把之前的事件给派发出去
这个应该是最核心的方法了!实例化所有剩余的(非惰性初始化)单例,说的多么的精确
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 类型转换
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
//值解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// aspectj 切面
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时 ClassLoader 进行类型匹配
beanFactory.setTempClassLoader(null);
// 允许缓存所有 bean 定义元数据,而不是期望进一步的更改
beanFactory.freezeConfiguration();
// 核心方法来了!!!
beanFactory.preInstantiateSingletons();
}
@Overridepublic void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) {//我今天才理解这个英语单词,trace轨迹级别,流程级别 logger.trace("Pre-instantiating singletons in " + this); } //直接获取了400多个bean的名字,当然我这是一个项目,正常组件肯定没有这么多,但你不在项目中看,全不是你自己定义你,你怎么去学习原理呢 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { //获取并合并本地的bean的定义信息,就像mybatis的那个保存xml配置的什么 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //不能是抽象的,必须是单例的,不能是懒加载的 if (isFactoryBean(beanName)) {//反正就是判断是不是工厂bean,简单看一下源码好像是支持父工厂,你说我没用过,我这个真不好看 //自动给你把前缀加上,获取实际的bean,这个我用过,我就一下知道了 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; //我看了一下,除了spring自己的,我定义的mapper,也是这个里面,那mbatis动态代理结合spring的原理我也能慢慢想出来了,希望自己也能开发这样一个只需要接口就能实现的框架吧,接口定义规范,我直接实现! boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else {//我们直接弄的bean就是走的这个分支 getBean(beanName); } } } //bean创建完毕,加入缓存 // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { //执行接口SmartInitializingSingleton方法,这个时候,一切都完成了,而且这个是全局性质的生命周期 StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize") .tag("beanName", beanName); SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } smartInitialize.end(); } }}
getBean实际执行的是这个,我调了一个自己定义的bean,看看是怎么实现的
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
//获取以前就创建好的单实例bean,这个里面好好多map,应该是三级缓存
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {//第一次创建肯定走的这条路
//确保它没有循环依赖,这个逻辑应该是反向判断出来的
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//检查此工厂中是否存在 bean 定义,包括以及父工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);//标记这个bean已经创建,防止多线程,这是一个典型的二重判断锁
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
//获取bean的定义信息,我看了一下,这个里面的东西还真是少啊
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);//检查是否为抽象类,如果是抽象类则报错
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
//这个依赖和我想的注入竟然是不一样的,这个是xml以前的那种配置,就是在创建这个bean之前你必须创建xxxbean出来
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {//如果先创建的bean还需要依赖我,那一准是循环依赖
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);//如果没有循环依赖的话,就直接getBean递归就行
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {//单实例
sharedInstance = getSingleton(beanName, () -> {
//以前没有lambda是一个ObjectFactory,那核心方法不用说,唉这args是什么鬼,从堆栈看到的,这肯定都是null啊,难道是那种使用有参钩子方法创建的bean吗
try {
return createBean(beanName, mbd, args);//明显这个是核心方法
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
创建bean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//确保此时实际解析了 bean 类,并克隆 bean 定义以防动态解析的 Class 无法存储在共享的合并 bean 定义中。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
//这个还是能检查方法是否重载啊,不愧是spring
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 让 BeanPostProcessors 有机会返回一个代理而不是目标 bean 实例。
//这是什么意思呢?源码里面设计到了这个接口,InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,这个默认返回的是null,如果不是null再触发一个后置的,配置类就是使用的这个,为什么它那么特殊,可以调用自己的方法,因为人家这里用的接口就不一样
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//又一个明显的核心方法,想这种复杂的核心流程,spring真的会套很多层的,而且你看它那个设计逻辑,真的就是方法的参数都是一样的,然后这样就把长的方法弄成短的了,哈哈哈
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {//一般这个肯定是要走的,我们看一下
//只是一个map的移除方法
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);//从缓存中移除
}
if (instanceWrapper == null) {
//创建bean示例
instanceWrapper = createBeanInstance(beanName, mbd, args);//最终返回的还是这个对象的wrapper,我的理解是代理增强
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//MergedBeanDefinitionPostProcessor接口定义的处理器,这个时候,仅仅是创建了一个空的对象,然后包装起来
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 即使被 BeanFactoryAware 等生命周期接口触发,也急切地缓存单例以解析循环引用,这里已经告诉你和循环引用有关系了
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//你看这熟悉的东西不就来了吗
populateBean(beanName, mbd, instanceWrapper);//为bean的属性赋值,DI注入完毕!!
exposedObject = initializeBean(beanName, exposedObject, mbd);//实现全局bean的生命周期,同时执行bean自己定义的生命周期,你注意看,这里执行了初始化接口和初始化方法,所以建议你用接口,用spring自带的这些,保证运行规律是正确的,建议用spring的接口,再次是spring的注释,java自带的支持逻辑可能都不一样,最好不要再使用了!
//而且我们的BeanPostProsser是包裹在所有的初始化方法前后的,逻辑肯定是先判断再执行,因为这个是针对所有bean的
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {//向缓存里面放
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);//一眼看出这个是核心方法
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 注册bean的销毁方法
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
创建实例,空对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);//获取bean的类型
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {//判断修饰符号,这个已经注定bean必须是public,不然你bean了个啥
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
//如果你是@Bean创建出来那,那么那个配置类就像是工厂,我们从那个里面拿
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// 构造函数装配,我猜里面肯定要按参数符合最多然后逐个实验
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 默认构造的首选构造函数
ctors = mbd.getPreferredConstructors();、
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 没有特殊处理:只需使用无参数构造函数。
return instantiateBean(beanName, mbd);//然后一路调用过后BeanUtils.instantiateClass完成了我们的使命
}
给属性赋值
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
//InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation
//在赋值之前,我要执行这个接口定义的方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//和Autowire有关的处理,我觉得就是beanFactory里面确定的那些
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//还是那个InstantiationAwareBeanPostProcessor接口不过是postProcessProperties方法
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
//这个才是核心的方法
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
为javabean对象设置属性值,实际上这个对象值不是你想的@Autowired要注入的东西,这个放到后面我再看
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);//执行aware方法
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {//执行我们最熟悉的BeanPostProcessor,BeforeInitialization初始化之前
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;
}
初始化方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);//这个不就是我们bean的生命周期接口吗
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {//这个类出现了好多次,听说Java要删除它了,就不管了
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();//执行它的关于属性创建之后的方法,看来这个属性和我们想想的属性并不一样啊
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);//执行bean定义时候的初始化方法,还考虑到了有人把这个方法就定义成了afterPropertiesSet,这个确实离谱
//卧槽,等一下,这个userService什么时候就被弄好了!!!???我刚刚看了一下,就是populateBean执行完后出现的,我去,再看一遍,这还能偷悄悄的给弄好了,这么关键的创建时机我可不能漏了,直接用排除法一个一个找!
}
}
}
就是这个循环,我先梳理一下,那个InstantiationAwareBeanPostProcessor(所以写这个接口的后置处理时,有那么一个时刻可能就完成依赖注入了)。肯定有一个是给这些内容赋值的,我只能慢慢回看,或者,咱们根据这个名称直接猜测一波AutowiredAnnotationBeanPostProcessor,名字起的极其明显,我们自己分析它,好像不太对唉,因为我用的@Resoure,所以我改成@Autowired再分析一波!AutowiredAnnotationBeanPostProcessor核心注入执行类!
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {//一切原理尽在眼前!!!!
ReflectionUtils.makeAccessible(field);//调整可见性
field.set(bean, value);//设置参数值
}
}
至此bean创建完毕,放到了ioc的map缓冲中!
protected void finishRefresh() {
// 清楚缓存
clearResourceCaches();
//初始化和生命周期有关的处理器
initLifecycleProcessor();//LifecycleProcessor接口,在启动和关闭的时候回调
// 和上面的关联,就是回调用上面组件的方法
getLifecycleProcessor().onRefresh();
// 事件发布,启动完成
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
initPropertySources
getEnvironment().getSystemProperties().put(“xx.xxx.xxx”,“属性值”);
原理对于spring来说属性Properties指的是这些
applyPropertyValues
Spring获取Bean的实例时,需要把配置的属性值解析到PropertyValues,然后填充入BeanWrapper中,依据上面那个你也多多少少懂一些这个的作用的,这些东西等我们后面再看,因为用所以学,这样学的效果才是最好的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。