南乐网站建设价格,珠海工程建设信息网站,免费自建手机网站,企业邮箱怎么注册免费文章目录 一、AOP的介绍1.1 基本概念1.2 AOP入门1.3 AOP工作流程1.4 切入点表达式1.5 AOP的通知类型1.6 ProceedingJoinPoint1.7 AOP通知获取参数数据 二、事物2.1 基本介绍2.2 事物角色2.3 事物属性2.4 事物的传播行为 一、AOP的介绍
1.1 基本概念 1.2 AOP入门
导入坐标 dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.2.10.RELEASE/version/dependencydependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.4/version/dependency定义dao接口和实现类
Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println(System.currentTimeMillis());System.out.println(book dao save ...);}public void update(){System.out.println(book dao update ...);}
}定义通知类定义切入点绑定切入点与通知的关系
//通知类必须配置成Spring管理的bean
Component
//设置当前类为切面类类
Aspect
public class MyAdvice {//设置切入点要求配置在方法上方Pointcut(execution(void com.itheima.dao.impl.BookDaoImpl.update()))private void pt(){}//设置在切入点pt()的前面运行当前操作前置通知Before(pt())public void method(){System.out.println(System.currentTimeMillis());}
}开启Spring对AOP注解驱动的支持
Configuration
ComponentScan(com.itheima)
//开启注解开发AOP功能
EnableAspectJAutoProxy
public class SpringConfig {
}1.3 AOP工作流程 1.4 切入点表达式 1.5 AOP的通知类型 after当前通知方法在原始切入点方法后运行before当前通知方法在原始切入点方法前运行AfterReturning当前通知方法在原始切入点方法正常执行完毕后执行AfterThrowing当前通知方法在原始切入点方法运行抛出异常后执行Around当前通知方法在原始切入点方法前后运行 演示
Component
Aspect
public class MyAdvice {Pointcut(execution(void com.itheima.dao.BookDao.update()))private void pt(){}Pointcut(execution(int com.itheima.dao.BookDao.select()))private void pt2(){}//Before前置通知在原始方法运行之前执行
// Before(pt())public void before() {System.out.println(before advice ...);}//After后置通知在原始方法运行之后执行
// After(pt2())public void after() {System.out.println(after advice ...);}//Around环绕通知在原始方法运行的前后执行
// Around(pt())public Object around(ProceedingJoinPoint pjp) throws Throwable {System.out.println(around before advice ...);//表示对原始操作的调用Object ret pjp.proceed();System.out.println(around after advice ...);return ret;}// Around(pt2())public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {System.out.println(around before advice ...);//表示对原始操作的调用Integer ret (Integer) pjp.proceed();System.out.println(around after advice ...);return ret;}//AfterReturning返回后通知在原始方法执行完毕后运行且原始方法执行过程中未出现异常现象
// AfterReturning(pt2())public void afterReturning() {System.out.println(afterReturning advice ...);}//AfterThrowing抛出异常后通知在原始方法执行过程中出现异常后运行AfterThrowing(pt2())public void afterThrowing() {System.out.println(afterThrowing advice ...);}
}1.6 ProceedingJoinPoint
Component
Aspect
public class ProjectAdvice {//配置业务层的所有方法Pointcut(execution(* com.itheima.service.*Service.*(..)))private void servicePt(){}//Around(ProjectAdvice.servicePt()) 可以简写为下面的方式Around(servicePt())public void runSpeed(ProceedingJoinPoint pjp){//获取执行签名信息Signature signature pjp.getSignature();//通过签名获取执行操作名称(接口名)String className signature.getDeclaringTypeName();//通过签名获取执行操作名称(方法名)String methodName signature.getName();long start System.currentTimeMillis();for (int i 0; i 10000; i) {pjp.proceed();}long end System.currentTimeMillis();System.out.println(万次执行 className.methodName---- (end-start) ms);}
}1.7 AOP通知获取参数数据
获取参数 获取返回值 获取异常 二、事物
2.1 基本介绍 在业务层接口的方法或者接口类表示里面所有方法都事务管理上添加事务管理注解Transactional
public interface AccountService {/*** 转账操作* param out 传出方* param in 转入方* param money 金额*///配置当前接口方法具有事务Transactionalpublic void transfer(String out,String in ,Double money) ;
}设置事务管理器创建一个事务管理的bean例如创建一个管理数据库的事物bean
public class JdbcConfig {Value(${jdbc.driver})private String driver;Value(${jdbc.url})private String url;Value(${jdbc.username})private String userName;Value(${jdbc.password})private String password;Beanpublic DataSource dataSource(){DruidDataSource ds new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}//配置事务管理器mybatis使用的是jdbc事务Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource){DataSourceTransactionManager transactionManager new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager;}
}开启注解式事务驱动
Configuration
ComponentScan(com.itheima)
PropertySource(classpath:jdbc.properties)
Import({JdbcConfig.class,MybatisConfig.class})
//开启注解式事务驱动
EnableTransactionManagement
public class SpringConfig {
}2.2 事物角色 2.3 事物属性
当代码抛出IOException异常时事物不会回滚因此我们需要设置Transactional(rollbackFor{IOException.class})来保证遇到IO异常时事物回滚。 2.4 事物的传播行为 1.REQUIRES_NEW解读 由于多个事物协调员由一个事物管理员管理当一个事物失败时其他事物也不能执行当我们需要保证一个事物协调员不会受其他事物影响时设置Transactional(propagationPropagation.REQUIRES_NEW)。
2.REQUIRES_NEW应用场景 当我们在转账时无论成功失败都需要向数据库中写入日志首先把转账与写日志写进一个转账Service的方法中并加上事务管理Transactional然后我们就需要在日志的Service接口的方法中加入Transactional(propagationPropagation.REQUIRES_NEW)。
日志接口与实现类LogService、LogServiceImpl
public interface LogService {//propagation设置事务属性传播行为设置为当前操作需要新事务Transactional(propagation Propagation.REQUIRES_NEW)void log(String out, String in, Double money);
}Service
public class LogServiceImpl implements LogService {Autowiredprivate LogDao logDao;public void log(String out,String in,Double money ) {logDao.log(转账操作由out到in,金额money);}
}转账接口和实现类AccountService、AccountServiceImpl
public interface AccountService {//rollback:设置当前事务参与回滚的异常默认非运行时异常不参与回滚
// Transactional(rollbackFor IOException.class)Transactionalpublic void transfer(String out,String in ,Double money) throws IOException;
}Service
public class AccountServiceImpl implements AccountService {Autowiredprivate AccountDao accountDao;Autowiredprivate LogService logService;public void transfer(String out,String in ,Double money) {try{accountDao.outMoney(out,money);int i 1/0;accountDao.inMoney(in,money);}finally {logService.log(out,in,money);}}}