一、基于注解方式的开发。
1.导入jar包:
除了基本的spring核心包以外,还需要引入spring-aop、aopalliance、aspectjweaver、spring-aspects.
创建applicationContext文件并开启aspectJ自动代理。
<aop:aspectj-autoproxy/>
2.AspectJ的通知类型:
@Before:前置通知
@AfterReturning:后置通知
@Around:环绕通知
@AfterThrowing:异常抛出通知
@After:一定会执行,无论有无异常
@DeclareParents:引介通知
3.简单案例
1.创建demo类productDao和切面类MyAspectAno
public class ProductDao { public void save(){ System.out.println("保存。。。。。"); } public void update(){ System.out.println("修改。。。。。"); } public void delete(){ System.out.println("删除。。。。。"); } public void findOne(){ System.out.println("查询一个。。。。。"); } public void findAll(){ System.out.println("查询所有。。。。。"); } }
//切面类 @Aspect public class MyAspectAno { @Before(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.save(..))") public void before(){ System.out.println("前置通知。。。。"); } }
2.测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringDemo1 { @Resource(name = "productDao") private ProductDao productDao; @Test public void demo1(){ productDao.save(); productDao.delete(); productDao.findAll(); productDao.findOne(); } }
3.通过使用Joinpoint获得切入点信息
public void before(JoinPoint joinPoint){ System.out.println("前置通知。。。。" + joinPoint); }
4、后置通知
@AfterReturning(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.delete (..))",returning = "result") public void afterReturning(JoinPoint joinPoint,Object result){ System.out.println("后置通知" + joinPoint + result); } }
使用returning属性来获取切入点的返回值
5.环绕通知(可以阻止目标方法的执行)
@Around(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.update (..))") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("======环绕前通知======"); Object obj = joinPoint.proceed(); //目标方法执行 System.out.println("======环绕后通知======"); return obj; }
6.异常抛出通知
@AfterThrowing(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.findOne (..))" , throwing = "throwing") public void afterThrowing(Throwable throwing){ System.out.println("异常抛出通知。。。。。" + throwing); }
使用throwing属性获得异常的属性。
7.最终通知
@After(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.findAll (..))") public void after(){ System.out.println("最终通知。。。。"); }
3.通过@pointcut为切点命名
@Pointcut(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.save (..))") private void myPointcut1(){}
二、基于xml方式的aspectJ的aop开发的简单案例
1.配置文件
<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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 使用xml配置方式--> <!-- 配置目标类--> <bean id="customerDao" class="com.imooc.aspectJ.demo2.CustomerDaoImp"/> <!-- 配置切面类--> <bean id="myAspectXml" class="com.imooc.aspectJ.demo2.MyAspectXml"> </bean> <!-- aop相关配置--> <aop:config> <!--配置切入点--> <aop:pointcut id="pointcut1" expression="execution(* com.imooc.aspectJ.demo2.CustomerDao.save(..) ))"/> <!--配置切面--> <aop:aspect ref="myAspectXml"> <!--配置前置通知--> <aop:before method="before" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config> </beans>
2.demo接口和类CustomerDao和CustomerDaoImp
public interface CustomerDao { public void save(); public void update(); public void delete(); public void findOne(); public void findAll(); }
public class CustomerDaoImp implements CustomerDao { @Override public void save() { System.out.println("保存客户。。。"); } @Override public void update() { System.out.println("修改客户。。。"); } @Override public void delete() { System.out.println("删除客户。。。"); } @Override public void findOne() { System.out.println("查询一个客户。。。"); } @Override public void findAll() { System.out.println("查询多个客户。。。"); } }
3.切面类
public class MyAspectXml { //前置通知 public void before(){ System.out.println("xml方式的前置通知"); } }