
通知类。
代码结构。

// pom.xml<?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>org.example</groupId><artifactId>text1</artifactId><version>1.0-SNAPSHOT</version><dependencies><!-- Spring常用依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.1.6.RELEASE</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!-- Junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies></project>
// User.java@Datapublic class User {}// IUserDao.javapublic interface IUserDao {void show();int addUser(User user);int updateUser(User user);int delUser(Integer id);}// UserDaoImpl.javapublic class UserDaoImpl implements IUserDao {@Overridepublic void show() {System.out.println("show");}@Overridepublic int addUser(User user) {// int i = 10/0;System.out.println("addUser\n");return 0;}@Overridepublic int updateUser(User user) {System.out.println("updateUser");return 0;}@Overridepublic int delUser(Integer id) {System.out.println("delUser");return 0;}}// IUserService.javapublic interface IUserService {void show();int addUser(User user);int updateUser(User user);int delUser(Integer id);}// UserServiceImpl.java@Datapublic class UserServiceImpl implements IUserService {private IUserDao userDao;@Overridepublic void show() {userDao.show();}@Overridepublic int addUser(User user) {return userDao.addUser(user);}@Overridepublic int updateUser(User user) {return userDao.updateUser(user);}@Overridepublic int delUser(Integer id) {return userDao.delUser(id);}}
// MyBefore.javapublic class MyBefore implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println("方法名:" + method.getName());System.out.println("参数:" + Arrays.toString(objects));System.out.println("目标名:" + o.getClass().getSimpleName());System.out.println("前置增强\n");}}
// MyAfter.javapublic class MyAfter implements AfterReturningAdvice {@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("方法返回值: "+o);System.out.println("方法名: "+ method.getName());System.out.println("参数: "+ Arrays.toString(objects));System.out.println("目标名: "+ o1.getClass().getSimpleName());System.out.println("后置增强\n");}}
// MyInterceptor.javapublic class MyInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation methodInvocation) throws Throwable {System.out.println("环绕增强前\n");// 核心方法 放行Object proceed = methodInvocation.proceed();System.out.println("环绕增强后\n");return proceed;}}
// MyException.java// 异常通知public class MyException implements ThrowsAdvice {public void afterThrowing(Exception ex) {System.out.println("出错啦..");}}
// application.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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl"></bean><bean id="userService" class="com.baidu.day.text.service.impl.UserServiceImpl"><property name="userDao" ref="userDao"></property></bean><!-- aop 配置增强类 --><bean id="myBefore" class="com.baidu.day.text.advice.MyBefore"></bean><bean id="myAfter" class="com.baidu.day.text.advice.MyAfter"></bean><bean id="myException" class="com.baidu.day.text.advice.MyException"></bean><bean id="myInterception" class="com.baidu.day.text.advice.MyInterceptor"></bean><aop:config><aop:pointcut id="myBeforePointCut" expression="execution(* com.baidu.day.text.service.IUserService.addUser(..))"/><aop:pointcut id="myAfterPointCut" expression="execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))"/><aop:advisor advice-ref="myException" pointcut="execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))"></aop:advisor><aop:advisor advice-ref="myInterception" pointcut="execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))"></aop:advisor><aop:advisor advice-ref="myBefore" pointcut-ref="myBeforePointCut"></aop:advisor><aop:advisor advice-ref="myAfter" pointcut-ref="myAfterPointCut"></aop:advisor></aop:config></beans>
匹配通配切入点。
匹配固定包名方法名execution(* com.baidu.day.text.service.impl.UserServiceImpl.addUser(..))匹配固定返回类execution(com.baidu.day.text.entity.User *(..))匹配固定参数execution(* *(com.baidu.day.text.entity.User))匹配包名、子包名execution(* com.baidu.day.text.service..*.*(..))匹配包名execution(* com.baidu.day.text.service.*.*(..))
// 测试@Testpublic void addUser() {ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");IUserService userService = (IUserService) ac.getBean("userService");userService.addUser(null);}// 打印环绕增强前方法名:addUser参数:[null]目标名:UserServiceImpl前置增强addUser方法返回值: 0方法名: addUser参数: [null]目标名: UserServiceImpl后置增强环绕增强后
Spring + MyBatis。
代码结构。

// pom.xml<?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>org.example</groupId><artifactId>text2</artifactId><version>1.0-SNAPSHOT</version><properties><spring.version>5.1.10.RELEASE</spring.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.3</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>5.1.47</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.8</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!-- jackjar jackson jar版本要和webMVC的版本一一对应 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.10.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><dependency><groupId>quartz</groupId><artifactId>quartz</artifactId><version>1.5.1</version></dependency><!-- Junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies><build><!-- 生成 war 的包名设置 --><!-- <finalName>xx.xx</finalName>--><resources><!-- 可关联的资源文件 --><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource></resources></build></project>
// jdbc.propertiesjdbc.username=rootjdbc.password=Liu01234jdbc.url=jdbc:mysql://localhost:3306/mydb1?characterEncoding=utf-8jdbc.driver=com.mysql.jdbc.Driver#<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计-->filters=stat#<!-- 配置初始化大小 -->initialSize=6#<!-- 配置初始化最大连接数 -->maxActive=20#<!-- 配置初始化最小连接数 -->minIdle=3#<!-- 配置获取连接等待超时的时间,1分钟单位毫秒 -->maxWait=60000#<!-- 检测连接是否有效的SQL -->validationQuery=SELECT ‘x‘#<!-- 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 -->testWhileIdle=true#<!-- 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->testOnBorrow=false#<!-- 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->testOnReturn=false#<!-- 启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true -->maxPoolPreparedStatementPerConnectionSize=20#<!-- 对于长时间不使用的连接强制关闭 -->removeAbandoned=true#<!-- 超过30秒的空闲连接就可以被关闭了,单位是秒 -->removeAbandonedTimeout=30#<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->timeBetweenEvictionRunsMillis=10000#<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->minEvictableIdleTimeMillis=30000
// Emp.java@Data@NoArgsConstructor@AllArgsConstructorpublic class Emp implements Serializable {private Integer empno;private String ename;private String job;private Integer mgr;private Date hiredate;private Double sal;private double comm;private Integer deptno;}// IEmpMapper.javapublic interface IEmpMapper {List<Emp> getAll();int addEmp(Emp e);}// IEmpService.javapublic interface IEmpService {List<Emp> getAll();int addEmp(Emp e);}// EmpServiceImpl.java@Datapublic class EmpServiceImpl implements IEmpService {private IEmpMapper empMapper;@Overridepublic List<Emp> getAll() {return empMapper.getAll();}@Overridepublic int addEmp(Emp e) {int tag = empMapper.addEmp(e);// 运行时异常int i = 10/0;return tag;}}
// EmpMapper.xml<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.baidu.day.text.dao.IEmpMapper"><insert id="addEmp" parameterType="emp">insert into emp(ename, job, mgr, sal, hiredate, comm, deptno)values(#{ename},#{job},#{mgr},#{sal},#{hiredate},#{comm},#{deptno})</insert><select id="getAll" resultType="emp">select * from emp</select></mapper>
// spring.xml<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 数据库 --><context:property-placeholder location="classpath*:jdbc.properties" /><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><!-- 别名 --><property name="typeAliasesPackage" value="com.baidu.day.text.entity" /><!-- <property name="mapperLocations">--><!-- <array>--><!-- <value>classpath*:com/baidu/day/text/mapper/*.xml</value>--><!-- </array>--><!-- </property>--><!-- 读取 mapper.xml 文件 --><property name="mapperLocations" value="classpath*:com/baidu/day/text/mapper/*.xml" /></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!-- mapper 接口包位置 bean name 首字母小写, IEmpMapper, i开头好像不用小写 --><property name="basePackage" value="com.baidu.day.text.dao" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /></bean><bean id="empService" class="com.baidu.day.text.service.impl.EmpServiceImpl"><property name="empMapper" ref="IEmpMapper" /></bean><!-- 事务 --><!-- 配置事务管理 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!-- 事务声明 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- timeout 超时时间;rollback-for,碰到什么样的报错回滚;propagation,事务隔离级别; --><!-- <tx:method name="addEmp" propagation="REQUIRED" rollback-for="Exception" timeout="60"/>--><tx:method name="show*" read-only="true" propagation="SUPPORTS"/><tx:method name="get*" read-only="true" propagation="SUPPORTS"/><tx:method name="select*" read-only="true" propagation="SUPPORTS"/><tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" /><tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" /><tx:method name="del*" propagation="REQUIRED" rollback-for="Exception" /><tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" /><tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception" /><!-- <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />--></tx:attributes></tx:advice><!-- 事务部署 --><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* com.baidu.day.text.service..*.*(..))"></aop:advisor></aop:config></beans>
// 测试@Testpublic void getAll() {ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");IEmpService empService = (IEmpService)ac.getBean("empService");List<Emp> all = empService.getAll();for (Emp emp : all) {System.out.println(emp);}}@Testpublic void addEmp() {ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");IEmpService empService = (IEmpService)ac.getBean("empService");Emp emp = new Emp();emp.setEname("张三");emp.setJob("程序员");emp.setHiredate(new Date());emp.setDeptno(10);emp.setComm(33.0);emp.setMgr(1);emp.setSal(22.0);int i = empService.addEmp(emp);System.out.println(i);}
<tx:method,事务属性。
isolation,隔离级别。级别越高,多事务并发时,越安全,并发越差。
default,采用数据库的默认的设置。
read-uncommited,读未提交。
read-commited,读提交,Oracle数据库默认的隔离级别。
repeatable-read,可重复读,MySQL 数据库默认的隔离级别。
serialized-read,序列化读,级别最高。
事务并发时的安全问题。
脏读,一个事务读取到另一个事务还未提交的数据,大于等于 read-commited 可防止。
不可重复读,一个事务内多次读取一行数据的相同内容,其结果不一致,大于等于 repeatable-read 可防止。
幻影读,一个事务内多次读取一张表中的相同内容,其结果不一致,serialized-read 可防止。
propagation,传播行为。
当涉及到事务嵌套(Service调用Service)时,可以设置。
SUPPORTS,不存在外部事务,则不开启新事务;存在外部事务,则合并到外部事务中。适合查询。
REQUIRED,不存在外部事务,则开启新事务;存在外部事务,则合并到外部事务中。默认值,适合增删改。
文章转载自java小小小小栈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




