protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
doc = <beans >跟标签,
attributes = [default-autowire="default", default-lazy-init="true", default-merge="default", xmlns="http://www.springframework.org/schema/beans", xmlns:aop="http://www.springframework.org/schema/aop", xmlns:cache="http://www.springframework.org/s...... ....... ......ta/jpahema/cache/spring-cache.xsd"]
children = [ [context:property-placeholder: null], [context:component-scan: null], [bean: dataSource], [bean: transactionManager], [aop:aspectj-autoproxy: null], [bean: jdbcTemplate], [tx:annotation-driven: null],]
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes(); //解析<beans>根节点,
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
解析[context:property-placeholder: null]标签,
delegate.parseCustomElement(ele); //ele = context:property-placeholder标签
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele); //http://www.springframework.org/schema/context,
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); //ContextNamespaceHandler里面找到解析类PropertyPlaceholderBeanDefinitionParser,
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); //名字是org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,内容是PropertySourcesPlaceholderConfigurer加入到spring的容器,解析的是core.properties里面的数据库的连接用户名密码地址信息。
locations = [classpath*:config/core/core.properties],
ignoreResourceNotFound = false,
localOverride = fasle
ignoreUnresolvablePlaceholders = false.
}
解析[context:component-scan: null]标签:(把扫描的bean的定义加到spring的容器)
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);//http://www.springframework.org/schema/context,
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);//ContextNamespaceHandler里面找到解析类ComponentScanBeanDefinitionParser,
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
public BeanDefinition parse(Element element, ParserContext parserContext) {
String[] basePackages = StringUtils.tokenizeToStringArray(element.getAttribute(BASE_PACKAGE_ATTRIBUTE),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);//[com.zhuguang.jack]
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);//ClassPathBeanDefinitionScanner,返回AnnotationServiceImpl的bean定义(并且已经加到容器中去了),
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
XmlReaderContext readerContext = parserContext.getReaderContext();//XmlReaderContext
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));//true
}
ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters);
scanner.setResourceLoader(readerContext.getResourceLoader());//ClassPathXmlApplicationContext
scanner.setEnvironment(parserContext.getDelegate().getEnvironment());
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
}
try {
parseBeanNameGenerator(element, scanner);
}
try {
parseScope(element, scanner);//解析context:component-scan标签的scope属性,
}
parseTypeFilters(element, scanner, readerContext, parserContext);//解析context:component-scan标签的TypeFilters属性,
return scanner;
}
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters); //里面有bean工厂,
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {//AnnotationServiceImpl
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry); //bean的定义注册到容器,
}
}
}
return beanDefinitions;
}
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + "/" + this.resourcePattern; //classpath*:com/zhuguang/jack/**/*.class,
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath); //AnnotationServiceImpl.class,MyService.class,Test2.class
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
if (isCandidateComponent(sbd)) {
candidates.add(sbd);
}
}
}
return candidates;//AnnotationServiceImpl
}
解析<bean id="dataSource">标签:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); //Bean definition with name 'dataSource' and aliases []: Generic bean: class [com.mchange.v2.c3p0.ComboPooledDataSource];
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); //注册到spring容器,
}
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE); //dataSource
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); //返回GenericBeanDefinition,里面的class = [com.mchange.v2.c3p0.ComboPooledDataSource]
if (beanDefinition != null) {
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); //beanDefinition = Generic bean: class [com.mchange.v2.c3p0.ComboPooledDataSource],beanName = dataSource , aliasesArray = [],
}
}
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) { //class属性,
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();//com.mchange.v2.c3p0.ComboPooledDataSource
}
try {
String parent = null;
AbstractBeanDefinition bd = createBeanDefinition(className, parent); //返回GenericBeanDefinition,里面的class = [com.mchange.v2.c3p0.ComboPooledDataSource]
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
return bd;
}
}
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) {
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); //true,
return bd;
}
解析<bean id="transactionManager">标签:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); //beanDefinition = Generic bean: class [org.springframework.jdbc.datasource.DataSourceTransactionManager]; beanName = transactionManager,
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); //注册到spring的容器,
}
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE); //transactionManager
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); //Generic bean: class [org.springframework.jdbc.datasource.DataSourceTransactionManager];
if (beanDefinition != null) {
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); //beanDefinition = Generic bean: class [org.springframework.jdbc.datasource.DataSourceTransactionManager]; beanName = transactionManager,
}
return null;
}
解析<aop:aspectj-autoproxy/>标签:
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);//http://www.springframework.org/schema/aop,
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); //handler = AopNamespaceHandler,
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); //AspectJAutoProxyBeanDefinitionParser
}
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);//注册AnnotationAwareAspectJAutoProxyCreator,名字叫做org.springframework.aop.config.internalAutoProxyCreator,内容是class [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator];到spring容器。最后包装成BeanComponentDefinition,名字还是叫org.springframework.aop.config.internalAutoProxyCreator,BeanComponentDefinition里面有AnnotationAwareAspectJAutoProxyCreator。
extendBeanDefinition(element, parserContext);
return null;
}
解析JdbcTemplate标签:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); //'jdbcTemplate' and aliases []: Generic bean: class [org.springframework.jdbc.core.JdbcTemplate];
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); //注册到spring容器,
}
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE); //jdbcTemplate
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); //Generic bean: class [org.springframework.jdbc.core.JdbcTemplate];
if (beanDefinition != null) {
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
}
解析[tx:annotation-driven: null]标签:
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); //TxNamespaceHandler
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); //AnnotationDrivenBeanDefinitionParser
}
public BeanDefinition parse(Element element, ParserContext parserContext) {
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
}
else {
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);//增加注解事务的入口类InfrastructureAdvisorAutoProxyCreator到spring容器,
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME; //internalTransactionAdvisor,
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element); //null
RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"); //事务属性的bean定义,里面有SpringTransactionAnnotationParser,去注解里面拿到属性值。
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
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);
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); //里面new TransactionAttributeSourcePointcut
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName); //TransactionInterceptor
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef); //internalTransactionAdvisor,BeanFactoryTransactionAttributeSourceAdvisor
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); //AnnotationTransactionAttributeSource,AnnotationTransactionAttributeSource#0
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName)); //TransactionInterceptor,TransactionInterceptor#0
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));//BeanFactoryTransactionAttributeSourceAdvisor,internalTransactionAdvisor
parserContext.registerComponent(compositeDef);
}
}
public static void registerAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { //internalAutoProxyCreator
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); //AnnotationAwareAspectJAutoProxyCreator
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {//cls = InfrastructureAdvisorAutoProxyCreator,
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
此时bean工厂里面有
[internalAutoProxyCreator,
PropertySourcesPlaceholderConfigurer#0,
annotationServiceImpl,
internalConfigurationAnnotationProcessor,
internalAutowiredAnnotationProcessor,
internalRequiredAnnotationProcessor,
internalCommonAnnotationProcessor,
dataSource,
transactionManager,
jdbcTemplate,
AnnotationTransactionAttributeSource#0,
TransactionInterceptor#0,
internalTransactionAdvisor,
ConfigurationClassPostProcessor.importAwareProcessor,
ConfigurationClassPostProcessor.enhancedConfigurationProcessor]
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
if (beanFactory instanceof BeanDefinitionRegistry) {
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //internalConfigurationAnnotationProcessor
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//ConfigurationClassPostProcessor
}
}
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);//注册ImportAwareBeanPostProcessor,EnhancedConfigurationBeanPostProcessor到spring容器,
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //internalConfigurationAnnotationProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //internalConfigurationAnnotationProcessor
}
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);//PropertySourcesPlaceholderConfigurer
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); //PropertySourcesPlaceholderConfigurer,解析jdbc的用户名密码地址。
}
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); //[internalAutoProxyCreator, internalAutowiredAnnotationProcessor, internalRequiredAnnotationProcessor, internalCommonAnnotationProcessor, ConfigurationClassPostProcessor.importAwareProcessor, ConfigurationClassPostProcessor.enhancedConfigurationProcessor]
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //[ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@acdb094, ConfigurationClassPostProcessor$EnhancedConfigurationBeanPostProcessor@674bd420, CommonAnnotationBeanPostProcessor@2b0f373b, AutowiredAnnotationBeanPostProcessor@2ceb80a1, RequiredAnnotationBeanPostProcessor@4b45dcb8]
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);//internalAutoProxyCreator(AnnotationAwareAspectJAutoProxyCreator),initializeBean方法里面的invokeAwareMethods方法设置this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory),
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, internalPostProcessors);//[CommonAnnotationBeanPostProcessor@2b0f373b, AutowiredAnnotationBeanPostProcessor@2ceb80a1, RequiredAnnotationBeanPostProcessor@4b45dcb8]
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
getBean(beanName); //internalAutoProxyCreator
getBean(AnnotationTransactionAttributeSource);解析AnnotationTransactionAttributeSource,createBeanInstance方法才会去调用构造函数,注册SpringTransactionAnnotationParser,JtaTransactionAnnotationParser,Ejb3TransactionAnnotationParser。findAdvisorBeans()方法会设置AnnotationAwareAspectJAutoProxyCreator的advisorRetrievalHelper 的cachedAdvisorBeanNames属性 = internalTransactionAdvisor。(getbean(“”)的时候,会执行所有的BeanPostProcessors的postProcessAfterInitialization方法,然后会给这些所有的BeanPostProcessors设置一些属性值。同时也会给正在实例化的bean设置一些属性值。)然后getbean("internalTransactionAdvisor"),
getBean(TransactionInterceptor);解析TransactionInterceptor,
MyService as = (MyService) context.getBean("annotationServiceImpl");
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {、
Object bean = resolveBeforeInstantiation(beanName, mbd);
Object beanInstance = doCreateBean(beanName, mbd, args);
return beanInstance;
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
}
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
}
return null;
}
AnnotationAwareAspectJAutoProxyCreator类:
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName); //AnnotationServiceImpl_annotationServiceImpl,beanClass = class com.zhuguang.jack.service.AnnotationServiceImpl,
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { //是否有Aspect注解,
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) { //null,不走,
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors(); //[org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0']
}
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;//internalTransactionAdvisor,cachedAdvisorBeanNames是AnnotationAwareAspectJAutoProxyCreator的属性,在解析AnnotationTransactionAttributeSource时候设置的缓存。
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class)); //org.springframework.transaction.config.internalTransactionAdvisor,返回[org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0']
}
}
}
}
return advisors;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
}
return result;
}
AnnotationAwareAspectJAutoProxyCreator类:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // //BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0' = TransactionInterceptor@7a138fc5,
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); //ProxyFactory: 1 interfaces [MyService]; 1 advisors [BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'TransactionInterceptor#0']; targetSource [[AnnotationServiceImpl@7c098bb3]];
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors(); //BeanFactoryTransactionAttributeSourceAdvisor
return super.shouldSkip(beanClass, beanName); //false
}
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List<Advisor> findAdvisorBeans() {
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames; //internalTransactionAdvisor
}
for (String name : advisorNames) {
advisors.add(this.beanFactory.getBean(name, Advisor.class)); //BeanFactoryTransactionAttributeSourceAdvisor
}
return advisors;
}
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
return eligibleAdvisors; //BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0' = TransactionInterceptor@7a138fc5,
}
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); //BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
return proxyFactory.getProxy(this.proxyClassLoader);
}
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
Advisor[] commonInterceptors = resolveInterceptorNames();//[]
List<Object> allInterceptors = new ArrayList<Object>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));//BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
if (commonInterceptors != null) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));//BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
}
}
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;//BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
}
as.saveTest1(111,111); // jdk动态代理,ProxyFactory: 1 interfaces [MyService]; 1 advisors [BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'TransactionInterceptor#0']; targetSource [[AnnotationServiceImpl@7c098bb3]];
JdkDynamicAopProxy类:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (target != null) {
targetClass = target.getClass(); //AnnotationServiceImpl
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //advised = ProxyFactory,targetClass = AnnotationServiceImpl,method = saveTest1(int,int)。返回TransactionInterceptor@560cbf1a。
else {
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
}
public Object proceed() throws Throwable { // 链式调用,
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
TransactionInterceptor类:
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); //AnnotationServiceImpl
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();//执行方法,又进到 链式调用,
}
});
}
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) {
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); //getTransactionAttributeSource() = AnnotationTransactionAttributeSource, 获取AnnotationServiceImpl类saveTest1(int,int)方法上的事务注解属性。返回PROPAGATION_REQUIRES_NEW,ISOLATION_READ_COMMITTED; '',传播属性和隔离级别。
final PlatformTransactionManager tm = determineTransactionManager(txAttr); //DataSourceTransactionManager@23a9ba52实例,
final String joinpointIdentification = methodIdentification(method, targetClass);//saveTest1方法名字,
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); //开启事务txInfo,返回PROPAGATION_REQUIRES_NEW,ISOLATION_READ_COMMITTED; '',
Object retVal = null;
try {
retVal = invocation.proceedWithInvocation(); //执行方法,
}
catch (Throwable ex) {
completeTransactionAfterThrowing(txInfo, ex);//回滚事务txInfo,
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);//提交事务txInfo,
return retVal;
}
}
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) { //获取AnnotationServiceImpl类saveTest1(int,int)方法上的事务注解属性
Object cacheKey = getCacheKey(method, targetClass);
Object cached = this.attributeCache.get(cacheKey);
if (cached != null) {
else {
return (TransactionAttribute) cached; //PROPAGATION_REQUIRES_NEW,ISOLATION_READ_COMMITTED; '',传播属性和隔离级别。
}
}
}
protected TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
status = tm.getTransaction(txAttr); //txAttr = PROPAGATION_REQUIRES_NEW,ISOLATION_READ_COMMITTED; '',返回//DefaultTransactionStatus@10b892d5
}
}
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
Object transaction = doGetTransaction(); //DataSourceTransactionManager$DataSourceTransactionObject@5aceec94,connectionHolder = null。
SuspendedResourcesHolder suspendedResources = suspend(null); //不挂起事务,因为没有事务,
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); //DefaultTransactionStatus@10b892d5
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;//DefaultTransactionStatus@10b892d5
}
}
protected Object doGetTransaction() {
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource()); //null,第一次没有事务返回null。
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
protected void doBegin(Object transaction, TransactionDefinition definition) { //开启事务,
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; //DataSourceTransactionManager$DataSourceTransactionObject@5aceec94
Connection con = null;
try {
if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon = obtainDataSource().getConnection();
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
con.setAutoCommit(false);
}
prepareTransactionalConnection(con, definition);
txObject.getConnectionHolder().setTransactionActive(true);
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}
}
protected void commitTransactionAfterReturning(TransactionInfo txInfo) { //通过conn提交事务,
if (txInfo != null && txInfo.hasTransaction()) {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
public final void commit(TransactionStatus status) throws TransactionException {
processCommit(defStatus);
}
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
doCommit(status);
}
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
try {
con.commit();
}
}
public class AnnotationServiceImpl implements MyService {
@Autowired
JdbcTemplate jdbcTemplate;
@Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED)
@Override
public void saveTest1(int param1,int param2) {
String sql = "insert into aa(id,name) values (?,?)";
int count = jdbcTemplate.update(sql, new Object[]{param1,param2});
throw new RuntimeException("saveTest1 异常");
}
protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) { //回滚事务,
if (txInfo != null && txInfo.hasTransaction()) {
if (txInfo.transactionAttribute.rollbackOn(ex)) {
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus()); //DataSourceTransactionManager,DefaultTransactionStatus
}
}
}
public final void rollback(TransactionStatus status) throws TransactionException {
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
processRollback(defStatus);
}
private void processRollback(DefaultTransactionStatus status) {
doRollback(status);
}
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
con.rollback();
}
@Service("annotationServiceImpl")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Lazy(false)
@Description("xx")
public class AnnotationServiceImpl implements MyService {
@Autowired
JdbcTemplate jdbcTemplate;
@Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED)
@Override
public void saveTest1(int param1,int param2) {
String sql = "insert into aa(id,name) values (?,?)";
int count = jdbcTemplate.update(sql, new Object[]{param1,param2});
// saveTest2(param1,param2);
}
@Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED)
@Override
public void saveTest2(int param1,int param2) {
String sql = "insert into aa(id) values (?)";
int count = jdbcTemplate.update(sql, new Object[]{param1,param2});
}
}
public interface MyService {
public void saveTest1(int param1,int para2);
public void saveTest2(int param1,int para2);
}
public class Test2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:config" + "/spring/applicationContext-core.xml");
MyService as = (MyService) context.getBean("annotationServiceImpl");
as.saveTest1(111,111);
}
}
core.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/upgrade?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=123456
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"
default-lazy-init="true">
<aop:aspectj-autoproxy/>
<!-- 导入外部属性文件 -->
<context:property-placeholder location="classpath*:config/core/core.properties" />
<context:component-scan base-package="com.zhuguang.jack"
use-default-filters="true" annotation-config="true">
</context:component-scan>
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--Transation-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhuguang.jack</groupId>
<artifactId>spring-source-web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-source-web Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>4.0.3.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version> </dependency> -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Jackson核心-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<!--
提供jackson核心支持
-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.9</version>
</dependency>
<!-- Jackson注解-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<!--
Jackson数据绑定包使用的核心注释,用于值类型。该包提供Json注解支持
-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<!--Jackson数据绑定-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<!--
对象序列化支持
-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>${spring.version}</version>
</dependency>-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- c3p0新版本 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.2.5</version>
</dependency>
<!-- 日志相关依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.37</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.9.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-cross-store</artifactId>
<version>1.9.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-log4j</artifactId>
<version>1.9.5.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--用于文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<!--velocity 模板-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>velocity-tools</groupId>
<artifactId>velocity-tools-generic</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<build>
<finalName>spring-source-web</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4</version>
<configuration>
<forkMode>once</forkMode>
<argLine>
-javaagent:"${settings.localRepository}/org/springframework/spring-instrument/${spring.version}/spring-instrument-${spring.version}.jar"
</argLine>
</configuration>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>