自定义注解是动态代理用的
基本的aop配置
一个接口DeptService
实现接口的类DeptServiceImpl,记得加上注解@Service,aop.xml扫描的时候会扫描到
有那个箭头,表示这些方法都需要切入一些内容
新建类DeptLog
方法:
public void before(){ System.out.println("DeptLog:before..."); } public void afterReturning(){ System.out.println("DeptLog:afterReturning..."); } public void after(){ System.out.println("DeptLog: after ..."); } public Object around(ProceedingJoinPoint jp) throws Throwable{ System.out.println("DeptLog: around before ..."); Object o = jp.proceed();// 执行方法 System.out.println("DeptLog: around after ..."); return o; } public void exception(Exception e){ System.out.println("DeptLog exception ... "+e.toString()); }
新建spring-aop.xml的配置文件,好测试
<context:component-scan base-package="com.zr"/> 扫描 <bean id="deptLog" class="com.zr.log.DeptLog"></bean> <aop:config>
设置aop的设置环境,即什么方法需要切入
<aop:pointcut expression="execution(* com.zr..*(..))" id="deptPointcut"/>扫描
所有在com.zr下的任意包的任意方法都要被植入新的方法
<aop:pointcut expression="execution(* com.zr.service..up*(..))" id="updateDeptPointcut"/>扫描 <aop:aspect ref="deptLog"> <aop:before method="before" pointcut-ref="deptPointcut"/>//表示所有的方法都切入before方法 <aop:after-returning method="afterReturning" pointcut-ref="deptPointcut"/> <aop:after method="after" pointcut-ref="deptPointcut"/> <aop:around method="around" pointcut-ref="updateDeptPointcut" />//表示service包下的up开头的方法都切入around方法 <aop:after-throwing method="exception" pointcut-ref="updateDeptPointcut" throwing="e"/> </aop:aspect> </aop:config>
测试的类AopTest
@Resource(name="deptService")
private DeptService service;
@Test
public void test() {
service.update();
}
20161123
<url-pattern>*.from</url-pattern>通过from表单提交的东西我这个分发器才做拦截,其他的不做拦截
AOP注解方式
aop.xml配置
<context:component-scan base-package="com.zr.service, com.zr.log"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>//true cglib的代理方式,jar包的
新建类DeptLog
记得加上Bean的注释@Component以及用@Aspect声明这是方面对象
@Component //不是控制器、服务层、数据库访问层都使用Component,通用的bean @Aspect //这是一个方面对象 public class DeptLog { @Before("execution(* com.zr.service..save*(..))")//只要符合这个插入规则就在这个范围下的方法下切入方法 public void before(){ System.out.println("DeptLog:before..."); } @AfterReturning("execution(* com.zr.service..save*(..))") public void afterReturning(){ System.out.println("DeptLog:afterReturning..."); } @After("execution(* com.zr.service..*(..))") public void after(){// 最终通知 System.out.println("DeptLog: after ..."); } @Around("execution(* com.zr.service..update*(..))") public Object around(ProceedingJoinPoint jp) throws Throwable{ System.out.println("DeptLog: around before ..."); Object o = jp.proceed();// 执行方法 System.out.println("DeptLog: around after ..."); return o; } @AfterThrowing(pointcut="execution(* com.zr.service..*(..))", throwing="e") public void afterThrowing(Exception e){ System.out.println("DeptLog exception ... " + e.toString()); } }
在类DeptLog的方法上写注解写规则
测试类AopTest:
@Resource(name="deptService")
private DeptService service;
@Test
public void test() {
service.save();
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
service.update();
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
service.delete();
}
//---------------------------------------------------------------------------------------------------
事务:
在spring-db.xml文件增加
声明事务管理组件
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
配置声明事物的范围及类型
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
记得添加回滚属性
<tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="java.sql.SQLException"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
使用AOP配置那些操作需要事务
<aop:config proxy-target-class="true"> //proxy-target-class="true"使用什么代理,设置为true表示cglp动态代理
(动态代理用两种,一种JDK自带一种cglp,区别JDK自带的代理对没接口的类不进行代理)
***service下的所有方法都添加了上面的事务***
<aop:advisor advice-ref="transactionAdvice" pointcut="execution(* com.zr.service..*(..))" />//在service包下切入事务
</aop:config>
隔离不代表回滚,rollback-for="java.sql.SQLException"当出现sql异常时候回滚
测试:
@Resource
private DeptService service;
@Test
public void test() {
Dept d1 = new Dept();
d1.setDeptno(90);
d1.setDname("0901开发班");
d1.setLoc("车陂");
service.save(d1);
d1 = new Dept();
d1.setDeptno(90);
d1.setDname("0902开发班");
d1.setLoc("车陂");
service.save(d1);
}
一次增加两个同样id的,会先把第一个80增加进去,然后数据库就有了,但是下面那个80在执行的时候会抛出异常说明有了
捕获这个异常,rollback-for="java.sql.SQLException"有了就回滚,两个都增加不进去
事务注解:db.xml下增加
<!-- 声明事务管理组件,DataSourceTransactionManager,无论使用注解还是配置XML方式都必须有 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 使用注解方式实现事务控制 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
在DeptServiceImpl这个类添加注解@Transactional(isolation=Isolation.READ_COMMITTED, rollbackFor=java.sql.SQLException.class)
/*
* 给当前类添加上事务控制
* @Transactional 可以添加在类上或方法上,如果在类上就是对本类的所有方法实现同样事务处理方式
* 如果是在方法,只针对添加注解的方法
*/