SpringBoot annotation transaction declarative transaction, springboot Annotation
Reprinted Please note: http://www.cnblogs.com/guozp/articles/7446477.html
Springboot may be faster for new users than springmvc. However, for springmvc to springboot, you need to adapt to some aspects, especially xml configuration. I personally prefer to annotate xml because it is convenient, convenient, and clear. However, xml can be replaced by annotations. Today, we will reveal how transactions in springboot use annotations.
Springboot transactions are mainly divided into two categories: xml declarative transactions and annotation transactions. annotation transactions can also implement methods similar to declarative transactions, currently, no suitable materials can be found on the Internet, so here I will write several methods I have searched for and summarized here for further discussion.
- Xml transactions in springboot
You can use @ ImportResource ("classpath: transaction. xml") to introduce the xml configuration. The xml configuration is as follows:
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" ></property> </bean> <tx:advice id="cftxAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="query*" propagation="SUPPORTS" read-only="true" ></tx:method> <tx:method name="get*" propagation="SUPPORTS" read-only="true" ></tx:method> <tx:method name="select*" propagation="SUPPORTS" read-only="true" ></tx:method> <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" ></tx:method> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution (* com.exmaple.fm..service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" order="0" /> </aop:config></beans>
The springboot startup class is as follows:
package com.example.fm;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;@ImportResource("classpath:transaction.xml")@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
The transaction can be started after the startup, but the xml configuration is imported in the project. If you do not want to import the xml configuration, you can use the annotation method.
- Springboot annotation transactions
Before explaining the annotation transactions, You need to first understand several classes for spring to create proxies. In spring, BeanPostProcessor is used to automatically create proxies. BeanPostProcessor interface is automatically loaded only when ApplicationContext is initialized, while BeanFactory can only be called programmatically. There are roughly three types of matching rules:
A. The matching Bean name automatically creates the matching Bean proxy and implements the BeanNameAutoProxyCreator class.
<bean id="testInterceptor" class="com.example.service.config.testInerceptor”></bean><bean id="profileAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyProxyCreator"><bean><property name="beanNames"><list><value>*Service</value></list></property><property name="interceptorNames"><value> testInterceptor </value></property></bean>
B. automatically create a proxy Based on the AspectJ annotation in Bean to implement AnnotationAwareAspectJAutoProxyCreator class
<aop:aspectj-autoproxy proxy-target-class="true"/><bean id="annotationAwareAspectJAutoProxyCreatorTest" class="com.example.service.AnnotationAwareAspectJAutoProxyCreatorTest"/><aop:config> <aop:aspect ref="annotationAwareAspectJAutoProxyCreatorTest"> <aop:around method="process" pointcut="execution (* com.example.service.fm..*.*(..))"/> </aop:aspect></aop:config>
C. automatically create a proxy Based on the Advisor matching mechanism. All the Advisor in the container will be scanned and automatically applied to the matched Bean to implement DefaultAdvisorAutoProxyCreator.
Next we will talk about how to enable the annotation transaction:
1. Transactional annotation transaction
Annotations need to be added to the method for thing Management@Transactional
Or, if you are lazy, add the annotation directly on the class so that all methods can manage things. However, you still need to add the Annotation on the class that requires transaction management, and the workload is relatively large, here is just a simple example. Specifically, google or bing
2. annotation declarative transactions
The difference between bean in Component or Configuration. I will write a special article to explain it if I have time.
A. method 1. Here, both Component and Configuration transactions can take effect.
Package com. exmple. service. fm9.config; import java. util. collections; import java. util. hashMap; import java. util. map; import org. aspectj. lang. annotation. aspect; import org. springframework. aop. advisor; import org. springframework. aop. aspectj. aspectJExpressionPointcut; import org. springframework. aop. support. defapointpointcutadvisor; import org. springframework. beans. factory. annotation. autowired; import org. springframework. context. annotation. bean; import org. springframework. context. annotation. configuration; import org. springframework. stereotype. component; import org. springframework. transaction. platformTransactionManager; import org. springframework. transaction. transactionDefinition; import org. springframework. transaction. interceptor. nameMatchTransactionAttributeSource; import org. springframework. transaction. interceptor. rollbackRuleAttribute; import org. springframework. transaction. interceptor. ruleBasedTransactionAttribute; import org. springframework. transaction. interceptor. transactionAttribute; import org. springframework. transaction. interceptor. transactionInterceptor;/*** Created by guozp on. * // @ Aspect // @ Component transaction still takes effect @ Configurationpublic class TxAdviceInterceptor {private static final int TX_METHOD_TIMEOUT = 5; private static final String AOP_POINTCUT_EXPRESSION = "execution (* com. alibaba. fm9 .. service. *. *(..)) "; @ Autowired private PlatformTransactionManager transactionManager; @ Bean public TransactionInterceptor txAdvice () {NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource ();/* read-only transaction, no update operation */RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute (); readOnlyTx. setReadOnly (true); readOnlyTx. setPropagationBehavior (TransactionDefinition. PROPAGATION_NOT_SUPPORTED);/* The current transaction is used for the current transaction, and a new transaction is created for the current transaction. */RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute (); requiredTx. setRollbackRules (Collections. singletonList (new RollbackRuleAttribute (Exception. class); requiredTx. setPropagationBehavior (TransactionDefinition. PROPAGATION_REQUIRED); requiredTx. setTimeout (TX_METHOD_TIMEOUT); Map <String, TransactionAttribute> txMap = new HashMap <> (); txMap. put ("add *", requiredTx); txMap. put ("save *", requiredTx); txMap. put ("insert *", requiredTx); txMap. put ("update *", requiredTx); txMap. put ("delete *", requiredTx); txMap. put ("get *", readOnlyTx); txMap. put ("query *", readOnlyTx); source. setNameMap (txMap); TransactionInterceptor txAdvice = new TransactionInterceptor (transactionManager, source); return txAdvice;} @ Bean public Advisor txAdviceAdvisor () {export pointcut = new AspectJExpressionPointcut (); pointcut. setExpression (AOP_POINTCUT_EXPRESSION); return new defapointpointcutadvisor (pointcut, txAdvice (); // return new DefaultPointcutAdvisor (pointcut, txAdvice );}}
B. method 1. Here, both Component and Configuration transactions can take effect.
Package com. exmple. service. fm9.config; import java. util. collections; import java. util. hashMap; import java. util. map; import org. springframework. aop. aspectj. aspectJExpressionPointcutAdvisor; import org. springframework. beans. factory. annotation. autowired; import org. springframework. context. annotation. bean; import org. springframework. context. annotation. configuration; import org. springframework. stereotype. component; import org. springframework. transaction. platformTransactionManager; import org. springframework. transaction. transactionDefinition; import org. springframework. transaction. interceptor. nameMatchTransactionAttributeSource; import org. springframework. transaction. interceptor. rollbackRuleAttribute; import org. springframework. transaction. interceptor. ruleBasedTransactionAttribute; import org. springframework. transaction. interceptor. transactionAttribute; import org. springframework. transaction. interceptor. transactionAttributeSource; import org. springframework. transaction. interceptor. transactionInterceptor;/*** Created by guozp on. * // @ Component transaction still effective @ Configurationpublic class TxAnoConfig {/* transaction interception type */@ Bean ("txSource") public TransactionAttributeSource transactionAttributeSource () {NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource ();/* read-only transaction, no update operation */RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute (); readOnlyTx. setReadOnly (true); readOnlyTx. setPropagationBehavior (TransactionDefinition. PROPAGATION_NOT_SUPPORTED);/* The current transaction is used for the current transaction, and a new transaction is created for the current transaction. * // RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute (); // requiredTx. setRollbackRules (// Collections. singletonList (new RollbackRuleAttribute (Exception. class); // requiredTx. setPropagationBehavior (TransactionDefinition. PROPAGATION_REQUIRED); RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute (TransactionDefinition. PROPAGATION_REQUIRED, Collections. singletonList (new RollbackRuleAttribute (Exception. class); requiredTx. setTimeout (5); Map <String, TransactionAttribute> txMap = new HashMap <> (); txMap. put ("add *", requiredTx); txMap. put ("save *", requiredTx); txMap. put ("insert *", requiredTx); txMap. put ("update *", requiredTx); txMap. put ("delete *", requiredTx); txMap. put ("get *", readOnlyTx); txMap. put ("query *", readOnlyTx); source. setNameMap (txMap); return source;}/** parameters are automatically injected from the container */@ Bean public AspectJExpressionPointcutAdvisor pointcutAdvisor (TransactionInterceptor txInterceptor) {AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor (); pointcutAdvisor. setAdvice (txInterceptor); pointcutAdvisor. setExpression ("execution (* com. alibaba. fm9 .. service. *. *(..)) "); return pointcutAdvisor;}/* transaction interceptor */@ Bean (" txInterceptor ") TransactionInterceptor getTransactionInterceptor (PlatformTransactionManager tx) {return new TransactionInterceptor (tx, transactionAttributeSource ());}}
C. method 1. Here, both Component and Configuration transactions can take effect.
Package com. exmple. service. fm9.config; import java. util. properties; import org. springframework. aop. framework. autoproxy. beanNameAutoProxyCreator; import org. springframework. beans. factory. annotation. autowired; import org. springframework. context. annotation. bean; import org. springframework. context. annotation. configuration; import org. springframework. jdbc. datasource. dataSourceTransactionManager; import org. springframework. stereotype. component; import org. springframework. transaction. interceptor. transactionInterceptor;/*** Created by guozp on. ** // @ Component @ Configurationpublic class TxConfigBeanName {@ Autowired private DataSourceTransactionManager transactionManager; // create a transaction notification @ Bean (name = "txAdvice") public TransactionInterceptor getAdvisor () throws Exception {Properties properties = new Properties (); properties. setProperty ("get *", "PROPAGATION_REQUIRED,-Exception, readOnly"); properties. setProperty ("add *", "PROPAGATION_REQUIRED,-Exception, readOnly"); properties. setProperty ("save *", "PROPAGATION_REQUIRED,-Exception, readOnly"); properties. setProperty ("update *", "PROPAGATION_REQUIRED,-Exception, readOnly"); properties. setProperty ("delete *", "PROPAGATION_REQUIRED,-Exception, readOnly"); TransactionInterceptor tsi = new TransactionInterceptor (transactionManager, properties); return tsi ;}@ Bean public BeanNameAutoProxyCreator txProxy () {BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator (); creator. setInterceptorNames ("txAdvice"); creator. setBeanNames ("* Service", "* ServiceImpl"); creator. setProxyTargetClass (true); return creator ;}}
D. method 1: Here, using Component or Configuration does not take effect for all transactions. For example, if the comments section is opened during Configuration and the code is not moved to defapointpointcutadvisor (), the transaction will become invalid, the specific cause is unknown for the moment. If you have any understanding, please give me some advice.
Ackage com. alibaba. fm9.config; import java. util. properties; import javax. SQL. dataSource; import org. springframework. aop. aspectj. aspectJExpressionPointcut; import org. springframework. aop. support. defapointpointcutadvisor; import org. springframework. beans. factory. annotation. autowired; import org. springframework. boot. autoconfigure. condition. conditionalOnMissingBean; import org. springframework. context. annotation. Bean; import org. springframework. context. annotation. configuration; import org. springframework. jdbc. datasource. dataSourceTransactionManager; import org. springframework. stereotype. component; import org. springframework. transaction. platformTransactionManager; import org. springframework. transaction. interceptor. transactionInterceptor;/*** Created by guozp on. *??????? * // @ Configuration // The transaction is invalid. Moving to a method is not invalid // @ Component // The transaction is feasible, you do not need to move to a public class txotherconfigdefabean bean {public static final String transactionExecution = "execution (* com. alibaba. fm9 .. service. *. *(..)) "; @ Autowired private PlatformTransactionManager transactionManager; // @ Bean // @ ConditionalOnMissingBean // public PlatformTransactionManager transactionManager () {// return new DataSourceTransactionManager (dataSource ); //} @ Bean public TransactionInterceptor transactionInterceptor () {Properties attributes = new Properties (); attributes. setProperty ("get *", "PROPAGATION_REQUIRED,-Exception"); attributes. setProperty ("add *", "PROPAGATION_REQUIRED,-Exception"); attributes. setProperty ("update *", "PROPAGATION_REQUIRED,-Exception"); attributes. setProperty ("delete *", "failed,-Exception"); // TransactionInterceptor txAdvice = new TransactionInterceptor (transactionManager (), attributes); TransactionInterceptor txAdvice = new TransactionInterceptor (transactionManager, attributes); return txAdvice;} // @ Bean // public AspectJExpressionPointcut aspectJExpressionPointcut () {// AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut (); // pointcut. setExpression (transactionExecution); // return pointcut; //} @ Bean public DefaultPointcutAdvisor defapointpointcutadvisor () {// AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut (); // pointcut. setExpression (transactionExecution); // DefaultPointcutAdvisor advisor = new defapointpointcutadvisor (); // advisor. setPointcut (pointcut); // advisor. setAdvice (transactionInterceptor (); AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut (); pointcut. setExpression (transactionExecution); defapointpointcutadvisor advisor = new defapointpointcutadvisor (); advisor. setPointcut (pointcut); Properties attributes = new Properties (); attributes. setProperty ("get *", "PROPAGATION_REQUIRED,-Exception"); attributes. setProperty ("add *", "PROPAGATION_REQUIRED,-Exception"); attributes. setProperty ("update *", "PROPAGATION_REQUIRED,-Exception"); attributes. setProperty ("delete *", "PROPAGATION_REQUIRED,-Exception"); TransactionInterceptor txAdvice = new TransactionInterceptor (transactionManager, attributes); advisor. setAdvice (txAdvice); return advisor ;}}
To put it simply, springboot uses the preceding annotations to enable things, which can achieve the same effect as declared in xml, but does not say goodbye to xml, so that your code is far away from the configuration file.
If something is wrong, I hope you can correct it. If you have other questions, contact
Reprinted Please note: http://www.cnblogs.com/guozp/articles/7446477.html