通常咱们会在datasource.xml中进行以下配置,可是其中每一个配置项原理和用途是什么,并非那么清楚,若是不清楚的话,在使用时候就颇有可能会遇到坑,因此下面对这些配置项进行一一解说java
(1)配置数据源 <bean id="dataSourace" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="${db_url}" /> <property name="username" value="$db_user}" /> <property name="password" value="${db_passwd}" /> <property name="maxWait" value="${db_maxWait}" /> <property name="maxActive" value="28" /> <property name="initialSize" value="2" /> <property name="minIdle" value="0" /> <property name="timeBetweenEvictionRunsMillis" value="db_time" /> </bean> (2)建立sqlSessionFactory <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="mapperLocations" value="classpath*:com/**/mapper/*Mapper*.xml" /> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="com.test.***.dal" /> </bean> (3)配置扫描器,扫描指定路径的mapper生成数据库操做代理类 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="annotationClass" value="javax.annotation.Resource"></property> <property name="basePackage" value="com.test.***.dal.***.mapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> (4)配置事务管理器 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> (5)声明使用注解式事务 <tx:annotation-driven transaction-manager="transactionManager" /> (6)注册各类beanfactory处理器 <context:annotation-config /> (7)该配置建立了一个TransactionInterceptor的bean,做为事务切面的执行方法 <tx:advice id="defaultTxAdvice"> <tx:attributes> <tx:method name="*" rollback-for="Exception" /> </tx:attributes> </tx:advice> (8)该配置建立了一个DefaultBeanFactoryPointcutAdvisor的bean,该bean是一个advisor,里面包含了pointcut和advice.前者说明切面加在哪里,后者是执行逻辑。此处能够配多个advisor <aop:config> <aop:pointcut id="myCut" expression="(execution(* *..*BoImpl.*(..))) "/> <aop:advisor pointcut-ref="myCut" advice-ref="defaultTxAdvice" /> </aop:config>
(1)是数据源配置,这个没啥好说的。spring
(2) 做用是根据配置建立一个SqlSessionFactory,看下SqlSessionFactoryBean的代码知道它实现了FactoryBean和InitializingBean类,因为实现了InitializingBean,因此天然它的afterPropertiesSet方法,因为实现了FactoryBean类,因此天然会有getObject方法。下面看下时序图:
从时序图可知,SqlSessionFactoryBean类主要是经过属性配置建立SqlSessionFactory实例,具体是解析配置中全部的mapper文件放到configuration,而后做为构造函数参数实例化一个DefaultSqlSessionFactory做为SqlSessionFactory。sql
MapperScannerConfigurer 实现了 BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware接口,因此会重写一下方法:数据库
1.3.1 //在bean注册到ioc后建立实例前修改bean定义和新增bean注册,这个是在context的refresh方法调用 void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; 1.3.2 //在bean注册到ioc后建立实例前修改bean定义或者属性值 void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; 1.3.3 //set属性设置后调用 void afterPropertiesSet() throws Exception; 1.3.4 //获取IOC容器上下文,在context的prepareBeanFactory中调用 void setApplicationContext(ApplicationContext applicationContext) throws BeansException; 1.3.5 //获取bean在ioc容器中名字,在context的prepareBeanFactory中调用 void setBeanName(String name);
先上个扫描mapper生成代理类并注册到ioc时序图:
首先MapperScannerConfigurer实现的afterPropertiesSet方法用来确保属性basePackage不为空express
public void afterPropertiesSet() throws Exception { notNull(this.basePackage, "Property 'basePackage' is required"); }
postProcessBeanFactory里面啥都没作,setBeanName获取了bean的名字,setApplicationContext里面获取了ioc上下文。下面看重要的方法postProcessBeanDefinitionRegistry,因为mybais是运行时候才经过解析mapper文件生成代理类注入到ioc,因此postProcessBeanDefinitionRegistry正好能够干这个事情。微信
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { if (this.processPropertyPlaceHolders) { processPropertyPlaceHolders(); } //构造一个ClassPathMapperScanner查找mapper ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); scanner.setAddToConfig(this.addToConfig); //javax.annotation.Resource scanner.setAnnotationClass(this.annotationClass); scanner.setMarkerInterface(this.markerInterface); //引用sqlSessionFactory scanner.setSqlSessionFactory(this.sqlSessionFactory); scanner.setSqlSessionTemplate(this.sqlSessionTemplate); scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName); scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName); //ioc上下文 scanner.setResourceLoader(this.applicationContext); scanner.setBeanNameGenerator(this.nameGenerator); scanner.registerFilters(); //basePackage=com.alibaba.***.dal.***.mapper,com.alibaba.rock.auth.mapper,com.alibaba.rock.workflow.dal.workflow.mapper scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); }
下面重点看下scan方法:session
public Set<BeanDefinitionHolder> doScan(String... basePackages) { //根据指定路径去查找对应mapper的接口类,并转化为beandefination Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages); if (beanDefinitions.isEmpty()) { logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration."); } else { //修改接口类bean的beandefination processBeanDefinitions(beanDefinitions); } return beanDefinitions; }
其中super.doScan(basePackages);根据指定路径查找mapper接口类,并生成bean的定义对象,对象中包含beanclassname,beanclass属性,最后注册该bean到ioc容器。下面看下最重要的processBeanDefinitions方法对bean定义的改造。mybatis
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) { GenericBeanDefinition definition; for (BeanDefinitionHolder holder : beanDefinitions) { definition = (GenericBeanDefinition) holder.getBeanDefinition(); // 上面讲的扫描后beanclass设置的为mapper接口类,可是这里修改成MapperFactoryBean,MapperFactoryBean代理了mapper接口类,而且实际mapper接口类做为构造函数传入了 definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName()); definition.setBeanClass(this.mapperFactoryBean.getClass()); definition.getPropertyValues().add("addToConfig", this.addToConfig); //设置属性配置中的sqlSessionFactory boolean explicitFactoryUsed = false; if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) { definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName)); explicitFactoryUsed = true; } else if (this.sqlSessionFactory != null) { definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory); explicitFactoryUsed = true; } if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) { if (explicitFactoryUsed) { logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); } definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName)); explicitFactoryUsed = true; } else if (this.sqlSessionTemplate != null) { if (explicitFactoryUsed) { logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); } definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate); explicitFactoryUsed = true; } if (!explicitFactoryUsed) { if (logger.isDebugEnabled()) { logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'."); } definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); } } }
注:这里修改了mapper接口类的beandefination中的beanclass为MapperFactoryBean,它则负责生产数据类操做代理类,实际mapper接口类做为构造函数传入了 。因为只修改了beanclass,没有修改beanname,因此咱们从容器中获取时候无感知的。oracle
在上一个代理bean如何构造的时序图:
下面看下MapperFactoryBean是如何生成代理类的:
首先,上面代码设置了MapperFactoryBean的setSqlSessionFactory方法:app
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { if (!this.externalSqlSession) { this.sqlSession = new SqlSessionTemplate(sqlSessionFactory); } }
上面方法建立了sqlSession,因为MapperFactoryBean为工厂bean因此实例化时候会调用getObject方法:
public T getObject() throws Exception { return getSqlSession().getMapper(this.mapperInterface); }
实际上是调用了SqlSessionTemplate->getMapper,其中mapperInterface就是建立MapperFactoryBean时候的构造函数参数。
public <T> T getMapper(Class<T> type) { return getConfiguration().getMapper(type, this); }
这里调用getConfiguration().getMapper(type, this);实际是DefaultSqlSessionFactory里面的configration的getMapper方法:
public <T> T getMapper(Class<T> type, SqlSession sqlSession) { //knownMappers是上面时序图中步骤6设置进入的。 final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } try { return mapperProxyFactory.newInstance(sqlSession); } catch (Exception e) { throw new BindingException("Error getting mapper instance. Cause: " + e, e); } } protected T newInstance(MapperProxy<T> mapperProxy) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); } public T newInstance(SqlSession sqlSession) { //代理回调类为MapperProxy final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); }
在上一个实际执行sql时候调用代理类的序列图:
因此当调用实际的数据库操做时候会调用MapperProxy的invoke方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (Object.class.equals(method.getDeclaringClass())) { try { return method.invoke(this, args); } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } } final MapperMethod mapperMethod = cachedMapperMethod(method); return mapperMethod.execute(sqlSession, args); }
mapperMethod.execute(sqlSession, args);里面实际是调用当前mapper对应的SqlSessionTemplate的数据库操做,而它有委托给了代理类sqlSessionProxy,sqlSessionProxy是在SqlSessionTemplate的构造函数里面建立的:
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) { notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required"); notNull(executorType, "Property 'executorType' is required"); this.sqlSessionFactory = sqlSessionFactory; this.executorType = executorType; this.exceptionTranslator = exceptionTranslator; this.sqlSessionProxy = (SqlSession) newProxyInstance( SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor()); }
因此最终数据库操做有被代理SqlSessionInterceptor执行:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //有TransactionSynchronizationManager管理 SqlSession sqlSession = getSqlSession( SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator); try { Object result = method.invoke(sqlSession, args); if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) { // force commit even on non-dirty sessions because some databases require // a commit/rollback before calling close() sqlSession.commit(true); } return result; } catch (Throwable t) { ..... } } public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) { notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED); notNull(executorType, NO_EXECUTOR_TYPE_SPECIFIED); SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); SqlSession session = sessionHolder(executorType, holder); if (session != null) { return session; } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Creating a new SqlSession"); } //这里看到了使用sessionfactory熟悉的打开了一个session session = sessionFactory.openSession(executorType); registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session); return session; }
注意:这里3里面配置的扫描文件在4的扫描文件里面必定要有,由于3给每一个扫描文件生成了一个代理,若是4里面多了一个mapper,那么在4中将找不到。
事务管理器做用见名知意,是用来管理事务的。
做用是建立了一个TransactionInterceptor的bean,做为事务切面的执行方法。标签解析的流程图:
因为是tx标签,天然要查找TxNamespaceHandler,代码以下:
public class TxNamespaceHandler extends NamespaceHandlerSupport { static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager"; static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager"; static String getTransactionManagerName(Element element) { return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ? element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME); } @Override public void init() { registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser()); registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser()); } }
从init方法知道advice标签须要TxAdviceBeanDefinitionParser这个解析类。
结合流程图第一步设置了事务管理器的引用,咱们看下引用的bean的名字:
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager"; static String getTransactionManagerName(Element element) { return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ? element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME); }
能够知道若是没有配置这个属性,那么默认查找依赖beanname=transactionManager。
而后parseAttributeSource主要循环解析咱们配置的method标签,和设置的方法的事务属性。
另外代码:
protected Class<?> getBeanClass(Element element) { return TransactionInterceptor.class; }
能够知道这个advice标签实际是创了TransactionInterceptor对象,而且经过调用setTransactionManager设置了事务管理器,经过setTransactionAttributeSources设置了事务属性。
标签做用是建立了DefaultBeanFactoryPointcutAdvisor做为拦截器,把知足切点的bean进行代理使用事务拦截器进行拦截。具体标签逻辑先看流程图:
从标签可知要查找AopNamespaceHandler,代码以下:
public class AopNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); } }
可知config标签是ConfigBeanDefinitionParser来解析的,根据流程图知configureAutoProxyCreator注册了AspectJAwareAdvisorAutoProxyCreator类,而后createAdvisorBeanDefinition建立了DefaultBeanFactoryPointcutAdvisor,它是个advisor,而且设置引用了advice,这个adivce就是上面1.5讲解的,而后createPointcutDefinition建立了切点AspectJExpressionPointcut,最后把切点设置到了advisor。
DefaultBeanFactoryPointcutAdvisor做用就是对知足pointcut表达式的类的方法进行代理,而且使用advice进行拦截处理,而advice就是事务拦截器。
上面介绍完后就可使用事务切面了,可是有时候还须要在具体类或者方法上进行注解行事务,那么这就须要加 配置
先上时序图:
!
同理1.6 不一样是这里建立了advisor,设置了advice(事务拦截器),可是好像没有设置pointcut,看下BeanFactoryTransactionAttributeSourceAdvisor源码知道:
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { private TransactionAttributeSource transactionAttributeSource; private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() { @Override protected TransactionAttributeSource getTransactionAttributeSource() { return transactionAttributeSource; } }; }
直接内置了pointcut,只不过1.6是AspectJExpressionPointcut表达式的切点,这里是注解。
那么这个BeanFactoryTransactionAttributeSourceAdvisor何时被用来加强注解事务的类那,那是InfrastructureAdvisorAutoProxyCreator所作的事情,InfrastructureAdvisorAutoProxyCreator是个BeanPostProcessor,会在bean建立初始化后时候调用postProcessAfterInitialization,就是这个方法。
另外注意若是配置了多个注解式标签在datasource.xml里面时候只有第一个生效
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME; //若是配置了多个注解式标签在datasource.xml里面时候只有第一个生效 if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) { Object eleSource = parserContext.extractSource(element); // Create the TransactionAttributeSource definition. RootBeanDefinition sourceDef = new RootBeanDefinition( "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"); sourceDef.setSource(eleSource); sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); // Create the TransactionInterceptor definition. RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef); // Create the TransactionAttributeSourceAdvisor definition. RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); advisorDef.getPropertyValues().add("adviceBeanName", interceptorName); if (element.hasAttribute("order")) { advisorDef.getPropertyValues().add("order", element.getAttribute("order")); } parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef); CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName)); compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName)); parserContext.registerComponent(compositeDef); } }
当咱们须要使用BeanPostProcessor时,最直接的使用方法是在Spring配置文件中定义这些Bean。单这些会显得比较笨拙,
例如:使用@Autowired注解,必须事先在Spring容器中声明
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>
使用 @Required注解,就必须声明:
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
经过标签 ,咱们能够同时自动注册这些经常使用的beanfactory处理器,避免了咱们一个个配置的繁琐步骤:
public class ContextNamespaceHandler extends NamespaceHandlerSupport { ... registerJava5DependentParser("annotation-config", "org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser"); .... } public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser { public BeanDefinition parse(Element element, ParserContext parserContext) { ... // Obtain bean definitions for all relevant BeanPostProcessors. Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source); // Register component for the surrounding <context:annotation-config> element. CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source); parserContext.pushContainingComponent(compDefinition); // Nest the concrete beans in the surrounding component. for (BeanDefinitionHolder processorDefinition : processorDefinitions) { parserContext.registerComponent(new BeanComponentDefinition(processorDefinition)); } // Finally register the composite component. parserContext.popAndRegisterContainingComponent(); return null; } } public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>(4); // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { ClassLoader cl = AnnotationConfigUtils.class.getClassLoader(); def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME)); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); beanDefinitions.add(registerBeanPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); beanDefinitions.add(registerBeanPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); beanDefinitions.add(registerBeanPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); beanDefinitions.add(registerBeanPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } return beanDefinitions; }
主要注册经常使用的:
RequiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
平时咱们使用autowired或者required之因此能生效,就是由于这个自动注入ioc已经。
欢迎关注微信公众号:技术原始积累 获取更多技术干货