spring源代码解析(三):spring

合集下载

(3)spring源码解析-refresh()方法之前

(3)spring源码解析-refresh()方法之前

(3)spring源码解析-refresh()⽅法之前本⽂是作者原创,版权归作者所有.若要转载,请注明出处.本⽂源码版本5.1.x.话不多说,开始⾸先是配置类@Configuration@ComponentScan("com.day01")public class SpringConfig {}IndexService@Servicepublic class IndexService {public IndexService(){System.out.println("IndexService 构造⽅法");}@PostConstructpublic void init(){System.out.println("IndexService init⽅法");}public void hello(){System.out.println("IndexService hello");}}测试类public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);//AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(IndexService.class);IndexService indexService = (IndexService) applicationContext.getBean("indexService");indexService.hello();System.out.println(indexService);}第⼀⾏点进去public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {//annotatedClasses ---> 配置类的class对象this();register(annotatedClasses);refresh();}今天我们先看refresh()⽅法之前的源码this()调的构造器如下public AnnotationConfigApplicationContext() {/*** ⽗类的构造⽅法* 创建⼀个读取注解的Bean定义读取器* 什么是BeanDefinition*/super();this.reader = new AnnotatedBeanDefinitionReader(this);//可以⽤来扫描包或者类,继⽽转换成BeanDefinition//但是实际上我们扫描包⼯作不是scanner这个对象来完成的//是spring⾃⼰new的⼀个ClassPathBeanDefinitionScanner//这⾥的scanner仅仅是为了程序员能够在外部调⽤AnnotationConfigApplicationContext对象的scan⽅法this.scanner = new ClassPathBeanDefinitionScanner(this);}/*** 这个类顾名思义是⼀个reader,⼀个读取器* 读取什么呢?还是顾名思义:AnnotatedBeanDefinition意思是读取⼀个被加了注解的BeanDefinition* 这个类在构造⽅法中实例化的*/private final AnnotatedBeanDefinitionReader reader;/*** 同意顾名思义,这是⼀个扫描器,扫描所有加了注解的bean* 同样是在构造⽅法中被实例化的*/private final ClassPathBeanDefinitionScanner scanner;先看super()⽗类构造器public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();}可以看出初始化beanFactory 为默认实现DefaultListableBeanFactory我们看⼀下些DefaultListableBeanFactory的属性和⽅法public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactoryimplements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {/** Map of bean definition objects, keyed by bean name. */private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);/** List of bean definition names, in registration order. */private volatile List<String> beanDefinitionNames = new ArrayList<>(256);//⼿动注册的单例对象的名称列表,按注册顺序排列/** List of names of manually registered singletons, in registration order. */private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);@Overridepublic <T> T getBean(Class<T> requiredType) throws BeansException {return getBean(requiredType, (Object[]) null);}@SuppressWarnings("unchecked")@Overridepublic <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {Assert.notNull(requiredType, "Required type must not be null");Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);if (resolved == null) {throw new NoSuchBeanDefinitionException(requiredType);}return (T) resolved;}}可以看出,这是bean⼯⼚的实现类,⾥⾯有存BeanDefinition和beanDefinitionNames 的map和getBean等⽅法⽗类构造器结束,就是实例了⼀个默认的bean⼯⼚,继续下⼀⾏this.reader = new AnnotatedBeanDefinitionReader(this);点进去看源码public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));}这⾥BeanDefinitionRegistry是⼀个BeanDefinition注册器public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");Assert.notNull(environment, "Environment must not be null");this.registry = registry;this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}继续看最后⼀⾏public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null);}继续跟进去public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);//AnnotationAwareOrderComparator主要能解析@Order注解和@Priority}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能}}//a Set of BeanDefinitionHolders, containing all bean definitions//BeanDefinitionHolder是存储BeanDefinitionName和BeanDefinition的⼀个数据结构Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);//BeanDefinitio的注册,这⾥很重要,需要理解注册每个bean的类型,CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME=internalConfigurationAnnotationProcessorif (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {//ConfigurationClassPostProcessor是⼀个BeanFactory的后置处理器,主要功能是解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解 //需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor//⽽ BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接⼝RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}//AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME=internalAutowiredAnnotationProcessorif (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {//AutowiredAnnotationBeanPostProcessor是解析AutoWired注解的BeanPostProcessor//AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor//MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessorRootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}//COMMON_ANNOTATION_PROCESSOR_BEAN_NAME=internalCommonAnnotationProcessor// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {//CommonAnnotationBeanPostProcessor⽀持对@PostConstruct和@PreDestroy注解,以及对@Resource注解的处理RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}//PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME=internalPersistenceAnnotationProcessor,跳过,不重要// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); }def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); }//EVENT_LISTENER_PROCESSOR_BEAN_NAME=internalEventListenerProcessorif (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {//EventListenerMethodProcessor⽀持事件监听,不太熟RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}//EVENT_LISTENER_FACTORY_BEAN_NAME=internalEventListenerFactoryif (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {//DefaultEventListenerFactory不太了解,事件监听相关RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;}这⾥的BeanDefinitionHolder看下public class BeanDefinitionHolder implements BeanMetadataElement {private final BeanDefinition beanDefinition;private final String beanName;@Nullableprivate final String[] aliases; //省略}可以认为:BeanDefinitionHolder是存储BeanDefinitionName和BeanDefinition的⼀个数据结构debug看下最后⼀⾏的结果可以看出,bean⼯⼚已经存在5个BeanDefinition,我们继续看下⾯的源码读取器看完了,扫描器先不看了,我们看register(annotatedClasses);⽅法public void register(Class<?>... annotatedClasses) {Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");this.reader.register(annotatedClasses);//被注解的类}继续跟下去public void register(Class<?>... annotatedClasses) {for (Class<?> annotatedClass : annotatedClasses) {registerBean(annotatedClass);}}这⾥循环处理所有要处理的annotated类。

spring事务管理器的源码和理解

spring事务管理器的源码和理解

以前说了大多的原理,今天来说下spring的事务管理器的实现过程,顺带源码干货带上。

其实这个文章唯一的就是带着看看代码,但是前提你要懂得动态代理以及字节码增强方面的知识(/xieyuooo/article/details/7624146),关于annotation在文章:/xieyuooo/article/details/8002321也有说明,所以本文也就带着看看代码而已。

关于annotation这里就不说了,我们看看平时一般会怎么样来配置spring的配置,通过配置文件反射源码如何看看。

一般来讲首先会配置一个datasource,至于你配置什么连接池还是用JNDI这里就不提到细节,总之我们认为配置的spring的全局名称为dataSource就可以了。

接下来会将datasource交给各种连接池的操作类,如:ibatis、jdbcTemplate等等,这些不是我们关心的重点,我们需要关心的是dataSource是谁来管理了,在spring中配置了给一个DataSourceTransactionManager的对象:<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource"><ref bean="dataSource" /></property></bean>ok,先记录下来,至于下面的NameMatchTransactionAttributeSource描述了那些情况要进行事务管理,我们将它理解为一种属性配置,在运行时需要解析即可,所以他也并不是我们特别需要的重点。

SpringIOC源码分析

SpringIOC源码分析

SpringIOC源码分析Spring 最重要的概念是 IOC 和 AOP,本篇⽂章其实就是要带领⼤家来分析下 Spring 的 IOC 容器。

既然⼤家平时都要⽤到 Spring,怎么可以不好好了解 Spring 呢?阅读本⽂并不能让你成为 Spring 专家,不过⼀定有助于⼤家理解 Spring 的很多概念,帮助⼤家排查应⽤中和Spring 相关的⼀些问题。

阅读建议:读者⾄少需要知道怎么配置 Spring,了解 Spring 中的各种概念,少部分内容我还假设读者使⽤过 SpringMVC。

本⽂要说的 IOC 总体来说有两处地⽅最重要,⼀个是创建 Bean 容器,⼀个是初始化 Bean,如果读者觉得⼀次性看完本⽂压⼒有点⼤,那么可以按这个思路分两次消化。

读者不⼀定对 Spring 容器的源码感兴趣,也许附录部分介绍的知识对读者有些许作⽤。

我采⽤的源码版本是 4.3.11.RELEASE,算是 5.0.x 前⽐较新的版本了。

为了降低难度,本⽂所说的所有的内容都是基于 xml 的配置的⽅式,实际使⽤已经很少⼈这么做了,⾄少不是纯 xml 配置,不过从理解源码的⾓度来看⽤这种⽅式来说⽆疑是最合适的。

如果读者对注解⽅式的源码感兴趣,也许等我有时间的时候可以写篇⽂章介绍介绍。

我希望能将此⽂写成⼀篇 Spring IOC 源码分析的好⽂章,希望通过本⽂可以让读者不惧怕阅读 Spring 源码。

为了保持⽂章的严谨性,如果读者发现我哪⾥说错了请⼀定不吝指出,⾮常希望可以听到读者的声⾳。

引⾔先看下最基本的启动 Spring 容器的例⼦:1 2 3public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationfile.xml"); }以上代码就可以利⽤配置⽂件来启动⼀个 Spring 容器了,请使⽤ maven 的⼩伙伴直接在 dependencies 中加上以下依赖即可,我⽐较反对那些不知道要添加什么依赖,然后把 Spring 的所有相关的东西都加进来的⽅式。

Spring源码分析-事件机制

Spring源码分析-事件机制

Spring源码分析-事件机制为了⽅便快速理解,我还是先不讲原理,直接⽰例开篇吧。

⼀、⽰例1.定义⼀个Listener 实现了ApplicationListener 接⼝@Componentpublic class MyTestListener implements ApplicationListener{@Overridepublic void onApplicationEvent(ApplicationEvent event) {System.out.println("向zookeeper注册暴露的服务...");}}2.applicationContext.xml 添加如下内容<context:annotation-config /><context:component-scan base-package="com.event"/>3.测试public class SpringEventTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");}}控制台输出:在这⾥不知道⼤家有没有发现,我这个main⽅法除了new ClassPathXmlApplicationContext("classpath:applicationContext.xml");其它什么也没做,那么为何MyTestListener 中的 onApplicationEvent ⽅法就执⾏了?⼆、源码分析1.先在⾃定义的listener类的 onApplicationEvent ⽅法进⾏断点调试(这⾥主要是为了通过Debug模式的线程栈查看从执⾏main⽅法开始到最后执⾏onApplicationEvent ⽅法结束都调⽤了哪些⽅法)2.Debug 运⾏测试类3.通过 Debug 线程栈分析源码执⾏过程(这⾥展⽰从main⽅法开始到onApplicationEvent⽅法的调⽤过程)从这个线程栈中可以看出,执⾏到refresh ⽅法中的finishRefresh 时,即执⾏publishEvent,关于refresh ⽅法我在这⾥不做过多的说明。

springaop源码分析(三)@Scope注解创建代理对象

springaop源码分析(三)@Scope注解创建代理对象

springaop源码分析(三)@Scope注解创建代理对象⼀.源码环境的搭建:@Component@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON,proxyMode = ScopedProxyMode.TARGET_CLASS)public class MyMath implements Calc{public Integer add(int num1,int num2){return num1+num2;}}@Configuration@ComponentScan("com.yang.xiao.hui.aop")public class App{public static void main( String[] args ){ApplicationContext ctx = new AnnotationConfigApplicationContext(App.class);MyMath myMath = (MyMath)ctx.getBean("myMath");System.out.println(myMath.getClass());System.out.println(ctx.getBean("scopedTarget.myMath").getClass());}}启动main⽅法:⼆.源码分析,先看Scope注解:scope注解的proxyMode的属性决定了被该注解标注的类是否会被代理,这是⼀个枚举,有如下⼏个值:本次测试代码使⽤的是cglib代理,被Scope标注的对象,如果代理模式是jdk或者cglib代理的话,会在spring容器中产⽣2个bean,⼀个是代理的bean,⼀个是原始的bean,原始的bean的beanName被命名为:scopedTarget.xx:debug调试:省略n步:我们在这个⽅法⾥⾯可以看到spring是如何解析主启动类,扫描到其他的bean的:protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) { //解析Component注解// Recursively process any member (nested) classes firstprocessMemberClasses(configClass, sourceClass);}// Process any @PropertySource annotationsfor (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class,org.springframework.context.annotation.PropertySource.class)) {if (this.environment instanceof ConfigurableEnvironment) {processPropertySource(propertySource);}else {("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +"]. Reason: Environment must implement ConfigurableEnvironment");}}// Process any @ComponentScan annotationsSet<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( //解析Component注解ComponentScan.classsourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);if (!componentScans.isEmpty() &&!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {// The config class is annotated with @ComponentScan -> perform the scan immediatelySet<BeanDefinitionHolder> scannedBeanDefinitions =ponentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); //componentScan解析器,对该注解进⾏解析// Check the set of scanned definitions for any further config classes and parse recursively if neededfor (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand == null) {bdCand = holder.getBeanDefinition();}if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());}}}}//..............................省略部分代码}protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();for (String basePackage : basePackages) {Set<BeanDefinition> candidates = findCandidateComponents(basePackage);//通过包名,扫描该包名下的所有bean的定义信息for (BeanDefinition candidate : candidates) {ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); //scope注解解析器,获取Scope注解的属性信息,封装成ScopeMetadatacandidate.setScope(scopeMetadata.getScopeName());String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);//beanName⽣成器,这⾥是myMathif (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); //这⾥处理scope注解,下⾯跟进这个beanDefinitions.add(definitionHolder);registerBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,BeanDefinitionRegistry registry, boolean proxyTargetClass) {String originalBeanName = definition.getBeanName();//原始的beanName: myMathBeanDefinition targetDefinition = definition.getBeanDefinition(); //原始的bean定义信息String targetBeanName = getTargetBeanName(originalBeanName); //scopedTarget.myMath// Create a scoped proxy definition for the original bean name,// "hiding" the target bean in an internal target definition.RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class); //创建⼀个代理对象proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName)); //将原始的bean定义信息作为被装饰的bean定义信息proxyDefinition.setOriginatingBeanDefinition(targetDefinition);//设置原始的bean定义信息proxyDefinition.setSource(definition.getSource());proxyDefinition.setRole(targetDefinition.getRole());proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);if (proxyTargetClass) {targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);// ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.}else {proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);}// Copy autowire settings from original bean definition.proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());proxyDefinition.setPrimary(targetDefinition.isPrimary());if (targetDefinition instanceof AbstractBeanDefinition) {proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);}// The target bean should be ignored in favor of the scoped proxy.targetDefinition.setAutowireCandidate(false);targetDefinition.setPrimary(false);// Register the target bean as separate bean in the factory.registry.registerBeanDefinition(targetBeanName, targetDefinition);//这⾥将原始的bean定义信息注册到了spring容器,⽽bean的名称是scopedTarget.myMath// Return the scoped proxy definition as primary bean definition// (potentially an inner bean).return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases()); //这⾥将代理bean定义信息返回,bean的名称是原始的beanName,myMath,该beanHodler返回去后,会被注册到spring }总结:⼀个被Scope注解标注的类,如果scope的proxyMode不是no 或者defualt,那么会在spring创建2个bean,⼀个是代理bean,类型为ScopedProxyFactoryBean.class,⼀个是原始的bean:这⾥我们的MyMath类,⽣成了2个beanDefinition,⼀个是代理的beanDefinition,beanName为myMath,⼀个是原始的beanDefinition,beanName为scopedTarget.myMath;下⾯我们要分析ScopedProxyFactoryBean的创建过程了,我们知道XXFactoryBean会有⼀个getObject()⽅法返回XX代理对象:先看ScopedProxyFactoryBean继承体系通过继承图,我们知道,ScopedProxyFactoryBean实现了BeanFactoryAware接⼝,因此在ScopedProxyFactoryBean的创建过程中,会回调setBeanFactory(BeanFactory beanFactory),所以我们debug在该⽅法:我们详细看看该⽅法:@Overridepublic void setBeanFactory(BeanFactory beanFactory) {if (!(beanFactory instanceof ConfigurableBeanFactory)) {throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory);}ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;this.scopedTargetSource.setBeanFactory(beanFactory);ProxyFactory pf = new ProxyFactory(); //创建代理⼯⼚pf.copyFrom(this);pf.setTargetSource(this.scopedTargetSource);Assert.notNull(this.targetBeanName, "Property 'targetBeanName' is required");Class<?> beanType = beanFactory.getType(this.targetBeanName);//获取被代理类if (beanType == null) {throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName +"': Target type could not be determined at the time of proxy creation.");}if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) {pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader())); //获取被代理类的所有实现的接⼝}// Add an introduction that implements only the methods on ScopedObject.ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName());pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject));//这⾥添加了⼀个增强器,在执⾏⽬标⽅法时,会拦截// Add the AopInfrastructureBean marker to indicate that the scoped proxy// itself is not subject to auto-proxying! Only its target bean is.pf.addInterface(AopInfrastructureBean.class);this.proxy = pf.getProxy(cbf.getBeanClassLoader());//创建代理对象}创建代理对象过程,跟之前aop源码分析⼀和源码分析⼆的时侯分析的⼀样了,这⾥不重复了。

Spring源码分析基本介绍

Spring源码分析基本介绍

Spring源码分析基本介绍摘要:本⽂结合《Spring源码深度解析》来分析Spring 5.0.6版本的源代码。

若有描述错误之处,欢迎指正。

前⾔作为⼀名开发⼈员,阅读源码是⼀个很好的学习⽅式。

本⽂将结合《Spring源码深度解析》来分析Spring 5.0.6版本的源代码,若有描述错误之处,欢迎指正。

Spring是2003年兴起的⼀个轻量级Java开源框架,旨在解决企业应⽤开发的复杂性。

Spring发展⾄今,衍⽣出⾮常丰富的模块,并应⽤在多种场景,⽐如:桌⾯应⽤,Web应⽤等。

Spring的模块化可以允许你只使⽤需要的模块,⽽不必全部引⼊。

⽬录⼀、整体架构1. 核⼼容器2. 数据访问/集成3. Web4. AOP5. Test⼆、设计理念三、使⽤场景1. 典型的Spring web应⽤程序2. Spring中间层使⽤第三⽅web框架3. 远程调⽤4. EJBs-包装现存POJOs⼀、整体架构Spring框架是⼀个分层架构,他包含⼀系列的功能要素,并被分为⼤约20个模块,如下图所⽰(很遗憾,并没有找到Spring5的架构图,下图是Spring4的,但结合Spring5的源码来看,该图还是能够体现Spring5的核⼼模块)这些模块被总结为以下⼏部分。

1. 核⼼容器Core Container(核⼼容器)包含有Core、Beans、Context和Expression Language模块。

Core和Beans模块是框架的基础部分,提供IoC(控制反转)和DI(依赖注⼊)特性。

这⾥的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。

Core模块主要包含Spring框架基本的核⼼⼯具类,Spring的其他组件都要使⽤到这个包⾥的类,Core模块是其他组件的基本核⼼。

当然你也可以在⾃⼰的应⽤系统中使⽤这些⼯具类。

Spring系列(三):SpringIoC源码解析

Spring系列(三):SpringIoC源码解析

Spring系列(三):SpringIoC源码解析⼀、Spring容器类继承图⼆、容器前期准备 IoC源码解析⼊⼝:/*** @desc: ioc原理解析启动* @author: toby* @date: 2019/7/22 22:20*/public class PrincipleMain {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PrincipleConfig.class);}} 调⽤构造函数AnnotationConfigApplicationContext 调⽤this(),会默认先调⽤⽗类的⽆参构造函数,为ApplicationContext上下⽂对象初始beanFactory = new DefaultListableBeanFactory() 在调⽤当前类的this(),也就是调⽤⾃⼰的⽆参构造函数: 进到创建注解模式下的Bean定义读取器: org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, ng.Object) 主要是注册Spring⾃⾝的⼀些后置处理器public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);/*** 为我们容器中注册解析主配置类的后置处理器ConfigurationClassPostProcessor* beanName = org.springframework.context.annotation.internalConfigurationAnnotationProcessor*/if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}/*** 为我们容器中注册处理@Autowired注解的Bean的后置处理器AutowiredAnnotationBeanPostProcessor* beanName = org.springframework.context.annotation.internalAutowiredAnnotationProcessor*/if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}/*** 为我们容器中注册处理@Required属性注解的Bean后置处理器RequiredAnnotationBeanPostProcessor* beanName = org.springframework.context.annotation.internalRequiredAnnotationProcessor*/if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}/*** 为我们容器注册处理JSR规范注解的Bean后置处理器CommonAnnotationBeanPostProcessor* beanName = org.springframework.context.annotation.internalCommonAnnotationProcessor*/if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}/*** 为我们容器注册处理jpa的Bean的后置处理器org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor*/if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}/*** 处理监听⽅法的注解解析器EventListenerMethodProcessor*/if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}/*** 注册事件监听器⼯⼚*/if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;} 读取器初始化完成后,Spring的容器的Bean的定义信息就有Spring⾃⾝的⼀些后置处理器了,Debug如下: 读取器初始化完成后,接下来初始化ClassPath下的Bean定义扫描器:org.springframework.context.annotation.ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner(org.springframework.beans.factory.support.BeanDefinitionRegistry, boolean, org.springframework.core.env.Environment, org.springframework.core.io.ResourceLoader) 类路径下的Bean定义扫描 org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#registerDefaultFilters 注⼊默认的Filterprotected void registerDefaultFilters() {this.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("d", cl)), false));logger.debug("JSR-330 'd' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}} 这⾥需要注意的是为什么new AnnotationTypeFilter(Component.class)就可以处理@Repository,@Service,@Controller这3个注解,原因如下: ⾃此前期准备⼯作完成三、org.springframework.context.support.AbstractApplicationContext#refresh 12⼤步public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//1:准备刷新上下⽂环境prepareRefresh();//2:获取初始化Bean⼯⼚ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//3:对bean⼯⼚进⾏填充属性prepareBeanFactory(beanFactory);try {//4:Spring开放接⼝留给⼦类去实现该接⼝postProcessBeanFactory(beanFactory);//5:调⽤我们的bean⼯⼚的后置处理器invokeBeanFactoryPostProcessors(beanFactory);//6:注册我们bean后置处理器registerBeanPostProcessors(beanFactory);//7:初始化国际化资源处理器initMessageSource();//8:初始化事件多播器initApplicationEventMulticaster();//9:这个⽅法同样也是留个⼦类实现,其中springboot也是从这个⽅法进⾏tomcat的启动onRefresh();//10:把我们的事件监听器注册到多播器上registerListeners();//11:实例化所有的⾮懒加载的单实例beanfinishBeanFactoryInitialization(beanFactory);//12:最后刷新容器发布刷新事件(Spring cloud eureka也是从这⾥启动的)finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}} 第⼀步:prepareRefresh() 准备刷新上下⽂环境:protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (logger.isInfoEnabled()) {("Refreshing " + this);}/*** 初始化上下⽂环境*/initPropertySources();/*** ⽤来校验我们容器启动必须依赖的环境变量的值*/getEnvironment().validateRequiredProperties();/*** 创建⼀个早期事件监听器对象*/if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}/*** 创建⼀个容器⽤于保存早期待发布的事件集合什么是早期事件了?* 就是我们的事件监听器还没有注册到事件多播器上的时候都称为早期事件*/this.earlyApplicationEvents = new LinkedHashSet<>();} 第⼆步:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() 获取初始化的Bean的⼯⼚:protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {//刷新bean⼯⼚()refreshBeanFactory();//返回之前容器准备⼯作的时候创建的的bean⼯⼚也就是DefaultListableBeanFactory(很重要)ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;} org.springframework.context.support.GenericApplicationContext#refreshBeanFactory,注意只能刷⼀次protected final void refreshBeanFactory() throws IllegalStateException {//由于BeanFactory只能刷新⼀次,多线程情况下可能导致线程安全问题,所有使⽤cas原⼦操作来保证if (!pareAndSet(false, true)) {throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");}//指定Bean⼯⼚的序列化Idthis.beanFactory.setSerializationId(getId());} 第三步:prepareBeanFactory(beanFactory) 对bean⼯⼚进⾏填充属性:protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {//设置bean⼯⼚的类加载器为当前application应⽤上下⽂的加载器beanFactory.setBeanClassLoader(getClassLoader());//为bean⼯⼚设置SPEL表达式解析器对象StandardBeanExpressionResolverbeanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));//为我们的bean⼯⼚设置了⼀个propertyEditor属性资源编辑器对象(⽤于后⾯的给bean对象赋值使⽤)beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));//注册ApplicationContextAwareProcessor后置处理器⽤来处理ApplicationContextAware接⼝的回调⽅法beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));/*** 当Spring将ApplicationContextAwareProcessor注册后,那么在invokeAwarelnterfaces⽅法中调⽤的Aware类已经不是普通的bean了,* 如ResourceLoaderAware、ApplicationEventPublisherAware、ApplicationContextAware等,那么当然需要在Spring做bean的依赖注⼊的时候忽略它们。

Spring MVC源码分析

Spring MVC源码分析

Request MappingHandlerA 基于@request Mapping对
dapt er
应方法处理
HandlerAdapt er 接口方法
HandlerAdapt er 接口结构图
ViewResolver 与View 详解 找到应的Adapt er 之后就会基于适配器调用业务处理,处理完之后业务方会返回一个 ModelAndView ,在去查找对应的视图进行处理。其在 org.springf ramework.web.servlet .Dispat cherServlet #resolveViewName() 中遍历 viewResolvers 列表查找,如果找不到就会报一个 Could not resolve view wit h name 异常。
5
mv.addObject("name","fox");
6
7
return mv;
8
}
9}
10
2.注解配置
1 <context:component-scan base-package=".controller" /> 2 <!-- 注解驱动 -->
3 <mvc:annotation-driven/>
4
xmlns:context="/schema/context"
5
xmlns:mvc="/schema/mvc"
6
xsi:schemaLocation="/schema/beans
1 // 注解方法
2 @RequestMapping("/hello.do")
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档