tx.xml事务配置文件的解析
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><context:property-placeholder location="classpath:dbconfig.properties"></context:property-placeholder><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property><property name="url" value="${jdbc.url}"></property><property name="driverClassName" value="${jdbc.driverClassName}"></property></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" ><constructor-arg name="dataSource" ref="dataSource"></constructor-arg></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><bean id="bookService" class="com.study.spring.tx.xml.service.BookService"><property name="bookDao" ref="bookDao"></property></bean><bean id="bookDao" class="com.study.spring.tx.xml.dao.BookDao"><property name="jdbcTemplate" ref="jdbcTemplate"></property></bean><aop:config><aop:pointcut id="txPoint" expression="execution(* com.study.spring.tx.xml.*.*.*(..))"/><aop:advisor advice-ref="myAdvice" pointcut-ref="txPoint"></aop:advisor></aop:config><tx:advice id="myAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="checkout" propagation="REQUIRED" /><tx:method name="updateStock" propagation="REQUIRES_NEW" /></tx:attributes></tx:advice><!-- <bean class="com.study.spring.MyBeanFactoryPostProcessorBySelf"></bean>-->
</beans>
PlaceholderConfigurerSupport类
spring提供的一个工具类,用于解析bean定义中属性值里面的占位符,此类不能被直接实例化使用
public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurerimplements BeanNameAware, BeanFactoryAware
会把 > <context:property-placeholder location=“classpath:dbconfig.properties”></context:property-placeholder>
这个标签解析替换${jdbc.username}这样的内容
aop标签解析
<aop:config><aop:pointcut id="txPoint" expression="execution(* com.study.spring.tx.xml.*.*.*(..))"/><aop:advisor advice-ref="myAdvice" pointcut-ref="txPoint"></aop:advisor></aop:config>
根据标签名找到对应的handler
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
AOP命名空间解析类。我们在用AOP的时候,会在Spring配置文件的beans标签中引入:xmlns:aop
public class AopNamespaceHandler extends NamespaceHandlerSupport {@Overridepublic void init() {// In 2.0 XSD as well as in 2.5+ XSDsregisterBeanDefinitionParser("config", new ConfigBeanDefinitionParser());registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());// Only in 2.0 XSD: moved to context namespace in 2.5+registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());}}
/**解析自定义元素(在默认名称空间之外)。* @param containingBd the containing bean definition (if any) @param containingBd包含bean的定义(如果有的话)* @return the resulting bean definition 得到的bean定义*/@Nullablepublic BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {// 获取对应的命名空间String namespaceUri = getNamespaceURI(ele);if (namespaceUri == null) {return null;}// 根据命名空间找到对应的NamespaceHandlerspringNamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);if (handler == null) {error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);return null;}// 调用自定义的NamespaceHandler进行解析 NamespaceHandlerSupportreturn handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));}
handler.parse调用的是NamespaceHandlerSupport的parse方法,因为AopNamespaceHandler extends NamespaceHandlerSupport
/*** 通过委托为{@link Element}注册的{@link BeanDefinitionParser}来解析提供的{@link Element}。*/@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) {// 获取元素的解析器BeanDefinitionParser parser = findParserForElement(element, parserContext);return (parser != null ? parser.parse(element, parserContext) : null);//ComponentScanBeanDefinitionParser的方法}
parser是ConfigBeanDefinitionParser:
public BeanDefinition parse(Element element, ParserContext parserContext) {CompositeComponentDefinition compositeDef =new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));parserContext.pushContainingComponent(compositeDef);
// 注册自动代理模式创建器,AspectjAwareAdvisorAutoProxyCreator 配置文件注解混合使用 context:commponentScan 注入innteral的类 这里也注入类似的类configureAutoProxyCreator(parserContext, element);List<Element> childElts = DomUtils.getChildElements(element);for (Element elt: childElts) {String localName = parserContext.getDelegate().getLocalName(elt);if (POINTCUT.equals(localName)) {parsePointcut(elt, parserContext);}else if (ADVISOR.equals(localName)) {parseAdvisor(elt, parserContext);}else if (ASPECT.equals(localName)) {parseAspect(elt, parserContext);}}parserContext.popAndRegisterContainingComponent();return null;}
configureAutoProxyCreator(parserContext, element);的功能是AspectJAwareAdvisorAutoProxyCreator引入。
pointcut 和 advisor 标签会在parsePointcut(elt, parserContext);和parseAdvisor(elt, parserContext);方法解析生成bean对象。
**parsePointcut(elt, parserContext);**最终createPointcutDefinition:
/*** Creates a {@link BeanDefinition} for the {@link AspectJExpressionPointcut} class using* the supplied pointcut expression.*/protected AbstractBeanDefinition createPointcutDefinition(String expression) {RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);beanDefinition.setSynthetic(true);beanDefinition.getPropertyValues().add(EXPRESSION, expression);return beanDefinition;}
<aop:pointcut id="txPoint" expression="execution(* com.study.spring.tx.xml.*.*.*(..))"/>对应AspectJExpressionPointcut
**parseAdvisor(elt, parserContext);**最终调用createAdvisorBeanDefinition:
/*** 解析advisor顾问类** Parses the supplied {@code <advisor>} element and registers the resulting* {@link org.springframework.aop.Advisor} and any resulting {@link org.springframework.aop.Pointcut}* with the supplied {@link BeanDefinitionRegistry}.*/private void parseAdvisor(Element advisorElement, ParserContext parserContext) {// 解析<aop:advisor>节点,最终创建的beanClass为`DefaultBeanFactoryPointcutAdvisor`// 另外advice-ref属性必须定义,其与内部属性adviceBeanName对应AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext);String id = advisorElement.getAttribute(ID);try {// 注册到bean工厂this.parseState.push(new AdvisorEntry(id));String advisorBeanName = id;if (StringUtils.hasText(advisorBeanName)) {parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);}else {advisorBeanName = parserContext.getReaderContext().registerWithGeneratedName(advisorDef);}// 解析point-cut属性并赋值到DefaultBeanFactoryPointcutAdvisor#pointcut内部属性Object pointcut = parsePointcutProperty(advisorElement, parserContext);if (pointcut instanceof BeanDefinition) {advisorDef.getPropertyValues().add(POINTCUT, pointcut);parserContext.registerComponent(new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));}else if (pointcut instanceof String) {advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));parserContext.registerComponent(new AdvisorComponentDefinition(advisorBeanName, advisorDef));}}finally {this.parseState.pop();}}
/*** Create a {@link RootBeanDefinition} for the advisor described in the supplied. Does <strong>not</strong>* parse any associated '{@code pointcut}' or '{@code pointcut-ref}' attributes.*/private AbstractBeanDefinition createAdvisorBeanDefinition(Element advisorElement, ParserContext parserContext) {RootBeanDefinition advisorDefinition = new RootBeanDefinition(DefaultBeanFactoryPointcutAdvisor.class);advisorDefinition.setSource(parserContext.extractSource(advisorElement));String adviceRef = advisorElement.getAttribute(ADVICE_REF);if (!StringUtils.hasText(adviceRef)) {parserContext.getReaderContext().error("'advice-ref' attribute contains empty value.", advisorElement, this.parseState.snapshot());}else {advisorDefinition.getPropertyValues().add(ADVICE_BEAN_NAME, new RuntimeBeanNameReference(adviceRef));}if (advisorElement.hasAttribute(ORDER_PROPERTY)) {advisorDefinition.getPropertyValues().add(ORDER_PROPERTY, advisorElement.getAttribute(ORDER_PROPERTY));}return advisorDefinition;}
<aop:advisor advice-ref="myAdvice" pointcut-ref="txPoint"></aop:advisor>对应DefaultBeanFactoryPointcutAdvisor.class
tx事务标签解析
<tx:advice id="myAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="checkout" propagation="REQUIRED" /><tx:method name="updateStock" propagation="REQUIRES_NEW" /></tx:attributes></tx:advice>
根据标签名找到对应的handler
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.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);}@Overridepublic void init() {// 注册不同的xml文件标签解析器registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());}}
/**解析自定义元素(在默认名称空间之外)。* @param containingBd the containing bean definition (if any) @param containingBd包含bean的定义(如果有的话)* @return the resulting bean definition 得到的bean定义*/@Nullablepublic BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {// 获取对应的命名空间String namespaceUri = getNamespaceURI(ele);if (namespaceUri == null) {return null;}// 根据命名空间找到对应的NamespaceHandlerspringNamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);if (handler == null) {error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);return null;}// 调用自定义的NamespaceHandler进行解析 NamespaceHandlerSupportreturn handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));}
handler.parse调用的是NamespaceHandlerSupport的parse方法,因为 TxNamespaceHandler extends NamespaceHandlerSupport
/*** 通过委托为{@link Element}注册的{@link BeanDefinitionParser}来解析提供的{@link Element}。*/@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) {// 获取元素的解析器BeanDefinitionParser parser = findParserForElement(element, parserContext);return (parser != null ? parser.parse(element, parserContext) : null);//ComponentScanBeanDefinitionParser的方法}
parser是AbstractBeanDefinitionParser
@Override@Nullablepublic final BeanDefinition parse(Element element, ParserContext parserContext) {AbstractBeanDefinition definition = parseInternal(element, parserContext);if (definition != null && !parserContext.isNested()) {try {String id = resolveId(element, definition, parserContext);if (!StringUtils.hasText(id)) {parserContext.getReaderContext().error("Id is required for element '" + parserContext.getDelegate().getLocalName(element)+ "' when used as a top-level tag", element);}String[] aliases = null;if (shouldParseNameAsAliases()) {String name = element.getAttribute(NAME_ATTRIBUTE);if (StringUtils.hasLength(name)) {aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));}}// 将AbstractBeanDefinition转换为BeanDefinitionHolder并注册BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);registerBeanDefinition(holder, parserContext.getRegistry());if (shouldFireEvents()) {// 通知监听器进行处理BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);postProcessComponentDefinition(componentDefinition);parserContext.registerComponent(componentDefinition);}}catch (BeanDefinitionStoreException ex) {String msg = ex.getMessage();parserContext.getReaderContext().error((msg != null ? msg : ex.toString()), element);return null;}}return definition;}
parseInternal(element, parserContext);是AbstractSingleBeanDefinitionParser的parseInternal方法
@Overrideprotected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();String parentName = getParentName(element);if (parentName != null) {builder.getRawBeanDefinition().setParentName(parentName);}// 获取自定义标签中的class,此时会调用自定义解析器Class<?> beanClass = getBeanClass(element);if (beanClass != null) {builder.getRawBeanDefinition().setBeanClass(beanClass);}else {// 若子类没有重写getBeanClass方法则尝试检查子类是否重写getBeanClassName方法String beanClassName = getBeanClassName(element);if (beanClassName != null) {builder.getRawBeanDefinition().setBeanClassName(beanClassName);}}builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));BeanDefinition containingBd = parserContext.getContainingBeanDefinition();if (containingBd != null) {// Inner bean definition must receive same scope as containing bean.// 若存在父类则使用父类的scope属性builder.setScope(containingBd.getScope());}if (parserContext.isDefaultLazyInit()) {// Default-lazy-init applies to custom bean definitions as well.// 配置延迟加载builder.setLazyInit(true);}// 调用子类重写的doParse方法进行解析doParse(element, parserContext, builder);return builder.getBeanDefinition();}
Class<?> beanClass = getBeanClass(element);调用的是TxAdviceBeanDefinitionParser的方法:
@Overrideprotected Class<?> getBeanClass(Element element) {return TransactionInterceptor.class;}
TransactionInterceptor
//事务拦截器,实现了方法拦截器MethodInterceptor
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {@Override@Nullablepublic Object invoke(MethodInvocation invocation) throws Throwable {// Work out the target class: may be {@code null}.// The TransactionAttributeSource should be passed the target class// as well as the method, which may be from an interface.// 获取我们的代理对象的class属性Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);// Adapt to TransactionAspectSupport's invokeWithinTransaction.../*** 以事务的方式调用目标方法* 在这埋了一个钩子函数 用来回调目标方法的*/return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);}
}
// 调用子类重写的doParse方法进行解析
doParse(element, parserContext, builder);
TxAdviceBeanDefinitionParser的doParse方法:
@Overrideprotected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {//<tx:advice标签有transaction-manager就取标签没有就取默认的DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";builder.addPropertyReference("transactionManager", TxNamespaceHandler.getTransactionManagerName(element));//<tx:advice id="myAdvice" transaction-manager="transactionManager">List<Element> txAttributes = DomUtils.getChildElementsByTagName(element, ATTRIBUTES_ELEMENT);if (txAttributes.size() > 1) {parserContext.getReaderContext().error("Element <attributes> is allowed at most once inside element <advice>", element);}else if (txAttributes.size() == 1) {// Using attributes source.Element attributeSourceElement = txAttributes.get(0);RootBeanDefinition attributeSourceDefinition = parseAttributeSource(attributeSourceElement, parserContext);builder.addPropertyValue("transactionAttributeSource", attributeSourceDefinition);}else {// Assume annotations source.builder.addPropertyValue("transactionAttributeSource",new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"));}}
TxAdviceBeanDefinitionParser的parseAttributeSource方法:
private RootBeanDefinition parseAttributeSource(Element attrEle, ParserContext parserContext) {List<Element> methods = DomUtils.getChildElementsByTagName(attrEle, METHOD_ELEMENT);ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap =new ManagedMap<>(methods.size());transactionAttributeMap.setSource(parserContext.extractSource(attrEle));for (Element methodEle : methods) {String name = methodEle.getAttribute(METHOD_NAME_ATTRIBUTE);TypedStringValue nameHolder = new TypedStringValue(name);nameHolder.setSource(parserContext.extractSource(methodEle));RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute();String propagation = methodEle.getAttribute(PROPAGATION_ATTRIBUTE);String isolation = methodEle.getAttribute(ISOLATION_ATTRIBUTE);String timeout = methodEle.getAttribute(TIMEOUT_ATTRIBUTE);String readOnly = methodEle.getAttribute(READ_ONLY_ATTRIBUTE);if (StringUtils.hasText(propagation)) {attribute.setPropagationBehaviorName(RuleBasedTransactionAttribute.PREFIX_PROPAGATION + propagation);}if (StringUtils.hasText(isolation)) {attribute.setIsolationLevelName(RuleBasedTransactionAttribute.PREFIX_ISOLATION + isolation);}if (StringUtils.hasText(timeout)) {try {attribute.setTimeout(Integer.parseInt(timeout));}catch (NumberFormatException ex) {parserContext.getReaderContext().error("Timeout must be an integer value: [" + timeout + "]", methodEle);}}if (StringUtils.hasText(readOnly)) {attribute.setReadOnly(Boolean.parseBoolean(methodEle.getAttribute(READ_ONLY_ATTRIBUTE)));}List<RollbackRuleAttribute> rollbackRules = new ArrayList<>(1);if (methodEle.hasAttribute(ROLLBACK_FOR_ATTRIBUTE)) {String rollbackForValue = methodEle.getAttribute(ROLLBACK_FOR_ATTRIBUTE);addRollbackRuleAttributesTo(rollbackRules, rollbackForValue);}if (methodEle.hasAttribute(NO_ROLLBACK_FOR_ATTRIBUTE)) {String noRollbackForValue = methodEle.getAttribute(NO_ROLLBACK_FOR_ATTRIBUTE);addNoRollbackRuleAttributesTo(rollbackRules, noRollbackForValue);}attribute.setRollbackRules(rollbackRules);transactionAttributeMap.put(nameHolder, attribute);}RootBeanDefinition attributeSourceDefinition = new RootBeanDefinition(NameMatchTransactionAttributeSource.class);attributeSourceDefinition.setSource(parserContext.extractSource(attrEle));attributeSourceDefinition.getPropertyValues().add("nameMap", transactionAttributeMap);return attributeSourceDefinition;}
<tx:attributes><tx:method name="checkout" propagation="REQUIRED" /><tx:method name="updateStock" propagation="REQUIRES_NEW" /></tx:attributes>
上述方法解析这些事务相关的标签,隔离级别、传播特性、超时时间、是否可读。这几个属性如果标签有设置就取没设置就用默认值。
方法最终返回了一个RootBeanDefinition,class是NameMatchTransactionAttributeSource.class
这一步完成,tx.xml文件的标签就解析完成,此时生成事务相关的如下:
此时befactory中bean定义信息如下:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property><property name="url" value="${jdbc.url}"></property><property name="driverClassName" value="${jdbc.driverClassName}"></property></bean>
上面的属性值还是${jdbc.username}变量接下来要进行替换,在invokeBeanFactoryPostProcessors(beanFactory);方法中执行。调用PropertySourcesPlaceholderConfigurer类的方法
invokeBeanFactoryPostProcessors执行结束之后:
registerBeanPostProcessors方法执行结束之后:
AspectJAwareAdvisorAutoProxyCreator对象生成在一级缓存:
因为class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupportimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor
interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor
相关对象的创建
对象的创建有如下几种方式:
接下来开始讲解存储在bean定义信息map里的十个对象的循环创建过程:以dataSource为例,
findAdvisorBeans:75, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:111, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
shouldSkip:101, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
postProcessBeforeInstantiation:252, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInstantiation:1145, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
resolveBeforeInstantiation:1118, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:505, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:897, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:879, AbstractApplicationContext (org.springframework.context.support)
refresh:551, AbstractApplicationContext (org.springframework.context.support)
<init>:144, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:85, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TxTest (com.study.spring.tx.xml)
applyBeanPostProcessorsBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;}
AbstractAdvisorAutoProxyCreator 类最终extends InstantiationAwareBeanPostProcessor 所以会进入调用postProcessBeforeInstantiation,才有了postProcessBeforeInstantiation:252, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
findAdvisorBeans
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);这个方法找到Advisor子类:org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0并返回
/*** Find all eligible Advisor beans in the current bean factory,* ignoring FactoryBeans and excluding beans that are currently in creation.* @return the list of {@link org.springframework.aop.Advisor} beans* @see #isEligibleBean*/public List<Advisor> findAdvisorBeans() {// Determine list of advisor bean names, if not cached already.String[] advisorNames = this.cachedAdvisorBeanNames;if (advisorNames == null) {// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the auto-proxy creator apply to them!advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);this.cachedAdvisorBeanNames = advisorNames;}if (advisorNames.length == 0) {return new ArrayList<>();}List<Advisor> advisors = new ArrayList<>();for (String name : advisorNames) {if (isEligibleBean(name)) {if (this.beanFactory.isCurrentlyInCreation(name)) {if (logger.isTraceEnabled()) {logger.trace("Skipping currently created advisor '" + name + "'");}}else {try {advisors.add(this.beanFactory.getBean(name, Advisor.class));}catch (BeanCreationException ex) {Throwable rootCause = ex.getMostSpecificCause();if (rootCause instanceof BeanCurrentlyInCreationException) {BeanCreationException bce = (BeanCreationException) rootCause;String bceBeanName = bce.getBeanName();if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {if (logger.isTraceEnabled()) {logger.trace("Skipping advisor '" + name +"' with dependency on currently created bean: " + ex.getMessage());}// Ignore: indicates a reference back to the bean we're trying to advise.// We want to find advisors other than the currently created bean itself.continue;}}throw ex;}}}}return advisors;}
实例化DefaultBeanFactoryPointcutAdvisor
advisors.add(this.beanFactory.getBean(name, Advisor.class));开始实例化DefaultBeanFactoryPointcutAdvisor
创建实例化DefaultBeanFactoryPointcutAdvisor对象的流程:
doCreateBean:559, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:516, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:207, AbstractBeanFactory (org.springframework.beans.factory.support)
findAdvisorBeans:91, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:111, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
shouldSkip:101, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
postProcessBeforeInstantiation:252, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInstantiation:1145, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
resolveBeforeInstantiation:1118, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:505, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:897, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:879, AbstractApplicationContext (org.springframework.context.support)
refresh:551, AbstractApplicationContext (org.springframework.context.support)
<init>:144, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:85, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TxTest (com.study.spring.tx.xml)
此时只创建对象没有进行属性填充,
populateBean:1400, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:593, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:516, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:207, AbstractBeanFactory (org.springframework.beans.factory.support)
findAdvisorBeans:91, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:111, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
shouldSkip:101, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
postProcessBeforeInstantiation:252, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInstantiation:1145, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
resolveBeforeInstantiation:1118, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:505, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:897, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:879, AbstractApplicationContext (org.springframework.context.support)
refresh:551, AbstractApplicationContext (org.springframework.context.support)
<init>:144, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:85, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TxTest (com.study.spring.tx.xml)
获取到需要填充的属性在这里和 <aop:config> <aop:pointcut id="txPoint" expression="execution(* com.study.spring.tx.xml.*.*.*(..))"/> <aop:advisor advice-ref="myAdvice" pointcut-ref="txPoint"></aop:advisor> </aop:config>
对应
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {for (PropertyValue pv : original) {if (pv.isConverted()) {deepCopy.add(pv);}else {String propertyName = pv.getName();Object originalValue = pv.getValue();if (originalValue == AutowiredPropertyMarker.INSTANCE) {Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();if (writeMethod == null) {throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);}originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);}Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);Object convertedValue = resolvedValue;boolean convertible = bw.isWritableProperty(propertyName) &&!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);if (convertible) {convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);}// Possibly store converted value in merged bean definition,// in order to avoid re-conversion for every created bean instance.if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);}deepCopy.add(pv);}else if (convertible && originalValue instanceof TypedStringValue &&!((TypedStringValue) originalValue).isDynamic() &&!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);deepCopy.add(pv);}else {resolveNecessary = true;deepCopy.add(new PropertyValue(pv, convertedValue));}}}}
resolveValueIfNecessary方法:
/*** Given a PropertyValue, return a value, resolving any references to other* beans in the factory if necessary. The value could be:* <li>A BeanDefinition, which leads to the creation of a corresponding* new bean instance. Singleton flags and names of such "inner beans"* are always ignored: Inner beans are anonymous prototypes.* <li>A RuntimeBeanReference, which must be resolved.* <li>A ManagedList. This is a special collection that may contain* RuntimeBeanReferences or Collections that will need to be resolved.* <li>A ManagedSet. May also contain RuntimeBeanReferences or* Collections that will need to be resolved.* <li>A ManagedMap. In this case the value may be a RuntimeBeanReference* or Collection that will need to be resolved.* <li>An ordinary object or {@code null}, in which case it's left alone.* @param argName the name of the argument that the value is defined for* @param value the value object to resolve* @return the resolved object*/@Nullablepublic Object resolveValueIfNecessary(Object argName, @Nullable Object value) {// We must check each value to see whether it requires a runtime reference// to another bean to be resolved.if (value instanceof RuntimeBeanReference) {RuntimeBeanReference ref = (RuntimeBeanReference) value;return resolveReference(argName, ref);}else if (value instanceof RuntimeBeanNameReference) {String refName = ((RuntimeBeanNameReference) value).getBeanName();refName = String.valueOf(doEvaluate(refName));if (!this.beanFactory.containsBean(refName)) {throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);}return refName;}else if (value instanceof BeanDefinitionHolder) {// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());}else if (value instanceof BeanDefinition) {// Resolve plain BeanDefinition, without contained name: use dummy name.BeanDefinition bd = (BeanDefinition) value;String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +ObjectUtils.getIdentityHexString(bd);return resolveInnerBean(argName, innerBeanName, bd);}else if (value instanceof DependencyDescriptor) {Set<String> autowiredBeanNames = new LinkedHashSet<>(4);Object result = this.beanFactory.resolveDependency((DependencyDescriptor) value, this.beanName, autowiredBeanNames, this.typeConverter);for (String autowiredBeanName : autowiredBeanNames) {if (this.beanFactory.containsBean(autowiredBeanName)) {this.beanFactory.registerDependentBean(autowiredBeanName, this.beanName);}}return result;}else if (value instanceof ManagedArray) {// May need to resolve contained runtime references.ManagedArray array = (ManagedArray) value;Class<?> elementType = array.resolvedElementType;if (elementType == null) {String elementTypeName = array.getElementTypeName();if (StringUtils.hasText(elementTypeName)) {try {elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());array.resolvedElementType = elementType;}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error resolving array type for " + argName, ex);}}else {elementType = Object.class;}}return resolveManagedArray(argName, (List<?>) value, elementType);}else if (value instanceof ManagedList) {// May need to resolve contained runtime references.return resolveManagedList(argName, (List<?>) value);}else if (value instanceof ManagedSet) {// May need to resolve contained runtime references.return resolveManagedSet(argName, (Set<?>) value);}else if (value instanceof ManagedMap) {// May need to resolve contained runtime references.return resolveManagedMap(argName, (Map<?, ?>) value);}else if (value instanceof ManagedProperties) {Properties original = (Properties) value;Properties copy = new Properties();original.forEach((propKey, propValue) -> {if (propKey instanceof TypedStringValue) {propKey = evaluate((TypedStringValue) propKey);}if (propValue instanceof TypedStringValue) {propValue = evaluate((TypedStringValue) propValue);}if (propKey == null || propValue == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error converting Properties key/value pair for " + argName + ": resolved to null");}copy.put(propKey, propValue);});return copy;}else if (value instanceof TypedStringValue) {// Convert value to target type here.TypedStringValue typedStringValue = (TypedStringValue) value;Object valueObject = evaluate(typedStringValue);try {Class<?> resolvedTargetType = resolveTargetType(typedStringValue);if (resolvedTargetType != null) {return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);}else {return valueObject;}}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error converting typed String value for " + argName, ex);}}else if (value instanceof NullBean) {return null;}else {return evaluate(value);}}
value instanceof RuntimeBeanNameReference 不会创建对象,虽然放到了deepCopy但是没对象。
value instanceof RuntimeBeanReference 调用resolveReference(argName, ref);会创建对象
<aop:pointcut id="txPoint" expression="execution(* com.study.spring.tx.xml.*.*.*(..))"/>
txPoint对象创建成功,属性经过初始化,并且befactory也赋值成功。
doCreateBean:604, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) [2]
createBean:516, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doGetBean:342, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
resolveReference:330, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
resolveValueIfNecessary:113, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
applyPropertyValues:1702, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
populateBean:1447, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:593, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) [1]
createBean:516, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:207, AbstractBeanFactory (org.springframework.beans.factory.support)
findAdvisorBeans:91, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:111, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
shouldSkip:101, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
postProcessBeforeInstantiation:252, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInstantiation:1145, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
resolveBeforeInstantiation:1118, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:505, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:897, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:879, AbstractApplicationContext (org.springframework.context.support)
refresh:551, AbstractApplicationContext (org.springframework.context.support)
<init>:144, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:85, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TxTest (com.study.spring.tx.xml)
继续回到DefaultBeanFactoryPointcutAdvisor属性填充的方法,此时该对象需要的两个属性已经实例化初始化完成一个了。
advice还是null,这个什么时候创建的呢?在后续需要创建代理对象的时候会创建AOP相关的这些对象的
回到BeanFactoryAdvisorRetrievalHelper 的findAdvisorBeans方法:advisors.add(this.beanFactory.getBean(name, Advisor.class));
findAdvisorBeans:91, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:111, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
shouldSkip:101, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
postProcessBeforeInstantiation:252, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInstantiation:1145, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
resolveBeforeInstantiation:1118, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:505, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 200404000 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:897, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:879, AbstractApplicationContext (org.springframework.context.support)
refresh:551, AbstractApplicationContext (org.springframework.context.support)
<init>:144, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:85, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TxTest (com.study.spring.tx.xml)
org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0这个对象创建完成放入了advisors中。
此时还有TransactionInterceptor没有实例化
继续回到datasource创建的过程中来
使用无参构造函数
获取构造函数之后开始实例化
开始进入无参构造
对象创建完成之后经过属性填充阶段,tx.xml中的几个变量也有值了。
BookService对象的创建:
BookService有个属性是BookDao,BookDao有个属性是JdbcTemplate,在创建BookService之前JdbcTemplate已经创建成功并且放在一级缓存了,创建service的时候要填充属性此时要去创建dao,创建dao的时候也要属性填充,此时创建JdbcTemplate,创建JdbcTemplate发先在缓存不用创建,直接返回就行。此时dao实例化属性填充完成了,但是根据
<aop:pointcut id=“txPoint” expression=“execution(* com.study.spring.tx.xml...*(…))”/>
要为dao创建代理对象。发生在
exposedObject = initializeBean(beanName, exposedObject, mbd);
这个方法继续进入
advice还是null,这个什么时候创建的呢?在后续需要创建代理对象的时候会创建AOP相关的这些对象的
getAdvice:116, AbstractBeanFactoryPointcutAdvisor (org.springframework.aop.support)
isAspectJAdvice:71, AspectJProxyUtils (org.springframework.aop.aspectj)
makeAdvisorChainAspectJCapableIfNecessary:52, AspectJProxyUtils (org.springframework.aop.aspectj)
extendAdvisors:95, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
findEligibleAdvisors:98, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:78, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
wrapIfNecessary:348, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
postProcessAfterInitialization:300, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:430, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1803, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:516, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 1852661033 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
resolveReference:330, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
resolveValueIfNecessary:113, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
applyPropertyValues:1702, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
populateBean:1447, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:593, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:516, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 1852661033 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:897, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:879, AbstractApplicationContext (org.springframework.context.support)
refresh:551, AbstractApplicationContext (org.springframework.context.support)
<init>:144, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:85, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TxTest (com.study.spring.tx.xml)
在这里会进行创建的
myadvice