1 静态代理

  • PersonDAO.java
  1. package com.xuweiwei.staticproxy;
  2.  
  3. public interface PersonDAO {
  4.  
  5. public void save();
  6.  
  7. }
  • PersonDAOImpl.java
  1. package com.xuweiwei.staticproxy;
  2.  
  3. public class PersonDAOImpl implements PersonDAO {
  4. @Override
  5. public void save() {
  6. System.out.println("保存用户信息");
  7. }
  8. }
  • Transaction.java
  1. package com.xuweiwei.staticproxy;
  2. //事务
  3. public class Transaction {
  4.  
  5. public void beginTransaction(){
  6. System.out.println("开启事务");
  7. }
  8.  
  9. public void commit(){
  10. System.out.println("提交");
  11. }
  12.  
  13. }
  • PersonDAOProxyImpl.java
  1. package com.xuweiwei.staticproxy;
  2.  
  3. public class PersonDAOProxyImpl implements PersonDAO {
  4. private PersonDAO personDAO;
  5. private Transaction transaction;
  6. public PersonDAOProxyImpl(PersonDAO personDAO,Transaction transaction){
  7. this.personDAO = personDAO;
  8. this.transaction = transaction;
  9. }
  10.  
  11. @Override
  12. public void save() {
  13. this.transaction.beginTransaction();
  14. this.personDAO.save();
  15. this.transaction.commit();
  16.  
  17. }
  18. }
  • 测试
  1. package com.xuweiwei.staticproxy;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class TestStatic {
  6.  
  7. @Test
  8. public void test(){
  9. PersonDAO personDAO = new PersonDAOImpl();
  10. Transaction transaction = new Transaction();
  11. PersonDAOProxyImpl proxy = new PersonDAOProxyImpl(personDAO,transaction);
  12. proxy.save();
  13. }
  14.  
  15. }
  • 缺点:

    • ①有多少DAO,就需要写多少proxy。
    • ②如果目标方法有方法的改动,proxy也需要做对应的缺点。

2 动态代理

2.1 JDK动态代理--基于接口的动态代理

  • PersonDAO.java
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. public interface PersonDAO {
  4.  
  5. public void save();
  6.  
  7. }
  • PersonDAOImpl.java
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. public class PersonDAOImpl implements PersonDAO {
  4. @Override
  5. public void save() {
  6. System.out.println("保存用户信息");
  7. }
  8. }
  • MyInterceptor.java
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.Method;
  5.  
  6. public class MyInterceptor implements InvocationHandler {
  7. private Object target ;
  8. private Transaction transaction;
  9.  
  10. public MyInterceptor(Object target, Transaction transaction) {
  11. this.target = target;
  12. this.transaction = transaction;
  13. }
  14.  
  15. @Override
  16. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  17.  
  18. this.transaction.beginTransaction();
  19. Object result = method.invoke(target,args);//调用目标类的目标方法
  20. this.transaction.commit();
  21.  
  22. return result;
  23. }
  24. }
  • Transaction.java
  1. package com.xuweiwei.dynamicproxy;
  2. //事务
  3. public class Transaction {
  4.  
  5. public void beginTransaction(){
  6. System.out.println("开启事务");
  7. }
  8.  
  9. public void commit(){
  10. System.out.println("提交");
  11. }
  12.  
  13. }
  • 测试
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.lang.reflect.Proxy;
  6.  
  7. public class TestDynamic {
  8.  
  9. @Test
  10. public void test(){
  11. PersonDAO personDAO = new PersonDAOImpl();
  12. Transaction transaction = new Transaction();
  13.  
  14. PersonDAO proxy = (PersonDAO) Proxy.newProxyInstance(personDAO.getClass().getClassLoader(),personDAO.getClass().getInterfaces(),new MyInterceptor(personDAO,transaction));
  15. proxy.save();
  16.  
  17. }
  18. }
  • 问:拦截器中的invoke方法是在什么时候被调用的?
  • 答:在代理对象调用方法的时候,进入拦截器中的invoke()方法。
  • 问:拦截器中的method参数是什么?在什么时候由实参传递给形参?
  • 答:代理对象调用方法的名称是什么,method参数就是什么。代理对象调用方法的时候,进入拦截器中的invoke()方法的时候,传递参数。
  • 问:生成的代理对象实现了接口,代理对象的方法体的内容是什么?
  • 答:代理对象方法体的内容就是拦截器中invoke()方法体的内容。  
  • 可以在拦截器中对指定的方法进行判断
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.Method;
  5.  
  6. public class MyInterceptor implements InvocationHandler {
  7. private Object target ;
  8. private Transaction transaction;
  9.  
  10. public MyInterceptor(Object target, Transaction transaction) {
  11. this.target = target;
  12. this.transaction = transaction;
  13. }
  14.  
  15. @Override
  16. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  17. Object result = null;
  18. if(method.getName().equals("save") || method.getName().equals("update")){
  19. this.transaction.beginTransaction();
  20. result = method.invoke(target,args);//调用目标类的目标方法
  21. this.transaction.commit();
  22. }else{
  23. result = method.invoke(target,args);//调用目标类的目标方法
  24. }
  25.  
  26. return result;
  27. }
  28. }
  • 优点:动态代理产生的对象,只需要一个拦截器就OK了。
  • 缺点:
    • 如果invoke方法中需要判断,将是一件非常复杂的事情。
    • 程序员需要写拦截器,写拦截器中的方法,所以invoke方法还需要修改  

2.2 CGLIB动态代理--基于类的动态代理

  • PersonDAO.java
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. public class PersonDAO {
  4.  
  5. public void save(){
  6. System.out.println("保存用户信息");
  7. }
  8. }
  • MyInterceptor.java
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. import org.springframework.cglib.proxy.Enhancer;
  4. import org.springframework.cglib.proxy.MethodInterceptor;
  5. import org.springframework.cglib.proxy.MethodProxy;
  6.  
  7. import java.lang.reflect.Method;
  8.  
  9. public class MyInterceptor implements MethodInterceptor {
  10. private Object target ;
  11. private Transaction transaction;
  12.  
  13. public MyInterceptor(Object target, Transaction transaction) {
  14. this.target = target;
  15. this.transaction = transaction;
  16. }
  17.  
  18. public Object createProxy(){
  19. Enhancer enhancer = new Enhancer();
  20. enhancer.setCallback(this);//this表示拦截器对象
  21. enhancer.setSuperclass(target.getClass());//设置代理类的父类为目标类
  22. return enhancer.create();
  23. }
  24.  
  25. @Override
  26. public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  27. this.transaction.beginTransaction();
  28. Object result = method.invoke(this.target,args);
  29. this.transaction.commit();
  30. return result;
  31. }
  32. }
  • Transaction.java
  1. package com.xuweiwei.dynamicproxy;
  2. //事务
  3. public class Transaction {
  4.  
  5. public void beginTransaction(){
  6. System.out.println("开启事务");
  7. }
  8.  
  9. public void commit(){
  10. System.out.println("提交");
  11. }
  12.  
  13. }
  • 测试
  1. package com.xuweiwei.dynamicproxy;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class TestDynamic {
  6.  
  7. @Test
  8. public void test(){
  9. PersonDAO target = new PersonDAO();
  10. Transaction transaction = new Transaction();
  11. MyInterceptor interceptor = new MyInterceptor(target,transaction);
  12. PersonDAO proxy = (PersonDAO) interceptor.createProxy();
  13. proxy.save();
  14.  
  15. }
  16. }

3 AOP的术语

  • 以2.1中的代码为例

  • 织入:形成代理对象的方法的过程就是织入。
  • 【注意】

    • 通知就是切面中的方法
    • 代理对象的方法就是通知+目标方法
    • 连接点就是目标接口中的一个方法
    • 拦截器中的invoke方法就是代理对象的方法=通知+目标方法
    • 在现实的开发中,通知和目标方法完全是松耦合的  

4 XML方式的AOP

  • PersonDAO.java
  1. package com.xuweiwei.aop;
  2.  
  3. public interface PersonDAO {
  4. public void savePerson();
  5.  
  6. }
  • PersonDAOImpl.java
  1. package com.xuweiwei.aop;
  2.  
  3. public class PersonDAOImpl implements PersonDAO {
  4. @Override
  5. public void savePerson() {
  6. System.out.println("保存用户信息");
  7. }
  8. }
  • Transaction.java
  1. package com.xuweiwei.aop;
  2. public class Transaction {
  3.  
  4. public void beginTransaction(){
  5. System.out.println("开启事务");
  6. }
  7.  
  8. public void commit(){
  9. System.out.println("提交");
  10. }
  11.  
  12. }
  • appliationContext.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  9.  
  10. <!-- 目标类 -->
  11. <bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
  12.  
  13. <!-- 切面 -->
  14. <bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
  15.  
  16. <!--
  17. 配置AOP
  18. -->
  19. <aop:config>
  20. <!--
  21. 配置切入点
  22. -->
  23. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
  24. <!--
  25. 配置切面
  26. -->
  27. <aop:aspect ref="transaction">
  28. <!--
  29. 前置通知
  30. -->
  31. <aop:before method="beginTransaction" pointcut-ref="pointcut"/>
  32.  
  33. <!--
  34. 最终通知
  35. -->
  36. <aop:after method="commit" pointcut-ref="pointcut"/>
  37.  
  38. </aop:aspect>
  39.  
  40. </aop:config>
  41.  
  42. </beans>
  • 测试
  1. package com.xuweiwei.test;
  2.  
  3. import com.xuweiwei.aop.PersonDAO;
  4. import org.junit.Test;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;
  7.  
  8. public class TestAOP {
  9. @Test
  10. public void test(){
  11. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  12. PersonDAO personDAO = (PersonDAO) context.getBean("personDAO");
  13. personDAO.savePerson();
  14.  
  15. }
  16. }

5 通知

  • 前置通知:在目标方法执行之前
  1. /**
  2. * 前置通知
  3. * JoinPoint:连接点,客户端调用那个方法,这个方法就是连接点
  4. */
  5. public void beginTransaction(JoinPoint joinPoint){
  6. System.out.println("目标类"+joinPoint.getTarget().getClass());
  7. System.out.println("目标方法"+joinPoint.getSignature().getName());
  8. System.out.println("目标类"+joinPoint.getArgs().length);
  9. System.out.println("开启事务");
  10. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  9.  
  10. <!-- 目标类 -->
  11. <bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
  12.  
  13. <!-- 切面 -->
  14. <bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
  15.  
  16. <!--
  17. 配置AOP
  18. -->
  19. <aop:config>
  20. <!--
  21. 配置切入点
  22. -->
  23. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
  24. <!--
  25. 配置切面
  26. -->
  27. <aop:aspect ref="transaction">
  28. <!--
  29. 前置通知
  30. -->
  31. <aop:before method="beginTransaction" pointcut-ref="pointcut"/>
  32.  
  33. </aop:aspect>
  34.  
  35. </aop:config>
  36.  
  37. </beans>
  • 后置通知,在目标方法执行之后(如果目标方法产生异常,后置通知不执行)
  1. package com.xuweiwei.aop;
  2.  
  3. public interface PersonDAO {
  4. public String savePerson();
  5.  
  6. }
  1. package com.xuweiwei.aop;
  2.  
  3. public class PersonDAOImpl implements PersonDAO {
  4. @Override
  5. public String savePerson() {
  6. System.out.println("保存用户信息");
  7. return "aa";
  8. }
  9. }
  1. package com.xuweiwei.aop;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4.  
  5. public class Transaction {
  6.  
  7. /**
  8. * 后置通知
  9. * @param joinPoint
  10. * @param val
  11. */
  12. public void commit(JoinPoint joinPoint,Object val){
  13. System.out.println("目标方法的返回值:"+val);
  14. System.out.println("提交");
  15. }
  16.  
  17. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  9.  
  10. <!-- 目标类 -->
  11. <bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
  12.  
  13. <!-- 切面 -->
  14. <bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
  15.  
  16. <!--
  17. 配置AOP
  18. -->
  19. <aop:config>
  20. <!--
  21. 配置切入点
  22. -->
  23. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
  24. <!--
  25. 配置切面
  26. -->
  27. <aop:aspect ref="transaction">
  28. <!--
  29. 后置通知
  30. -->
  31. <aop:after-returning method="commit" pointcut-ref="pointcut" returning="val"/>
  32.  
  33. </aop:aspect>
  34.  
  35. </aop:config>
  36.  
  37. </beans>
  • 异常通知:当发生异常的时候,此通知执行
  1. package com.xuweiwei.aop;
  2.  
  3. public interface PersonDAO {
  4. public String savePerson();
  5.  
  6. }
  1. package com.xuweiwei.aop;
  2.  
  3. public class PersonDAOImpl implements PersonDAO {
  4. @Override
  5. public String savePerson() {
  6. System.out.println("保存用户信息");
  7.  
  8. int a = 1/0;
  9.  
  10. return "aa";
  11. }
  12. }
  1. package com.xuweiwei.aop;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4.  
  5. public class Transaction {
  6.  
  7. public void throwingMethod(JoinPoint joinPoint,Throwable ex){
  8. System.out.println("发生异常:"+ex.getMessage());
  9. System.out.println("异常通知");
  10. }
  11.  
  12. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  9.  
  10. <!-- 目标类 -->
  11. <bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
  12.  
  13. <!-- 切面 -->
  14. <bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
  15.  
  16. <!--
  17. 配置AOP
  18. -->
  19. <aop:config>
  20. <!--
  21. 配置切入点
  22. -->
  23. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
  24. <!--
  25. 配置切面
  26. -->
  27. <aop:aspect ref="transaction">
  28. <!--
  29. 异常通知
  30. -->
  31. <aop:after-throwing method="throwingMethod" pointcut-ref="pointcut" throwing="ex"/>
  32.  
  33. </aop:aspect>
  34.  
  35. </aop:config>
  36.  
  37. </beans>
  • 最终通知:不管目标方法发生什么,都要执行此通知
  1. package com.xuweiwei.aop;
  2.  
  3. public class Transaction {
  4.  
  5. public void finallyMethod(){
  6. System.out.println("最终通知");
  7. }
  8.  
  9. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  9.  
  10. <!-- 目标类 -->
  11. <bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
  12.  
  13. <!-- 切面 -->
  14. <bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
  15.  
  16. <!--
  17. 配置AOP
  18. -->
  19. <aop:config>
  20. <!--
  21. 配置切入点
  22. -->
  23. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
  24. <!--
  25. 配置切面
  26. -->
  27. <aop:aspect ref="transaction">
  28. <!--
  29. 最终通知
  30. -->
  31. <aop:after method="finallyMethod" pointcut-ref="pointcut" />
  32.  
  33. </aop:aspect>
  34.  
  35. </aop:config>
  36.  
  37. </beans>
  • 环绕通知:在目标方法执行前后,此通知执行
  1. package com.xuweiwei.aop;
  2.  
  3. import org.aspectj.lang.ProceedingJoinPoint;
  4.  
  5. public class Transaction {
  6.  
  7. public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
  8. System.out.println("环绕通知执行前");
  9. joinPoint.proceed();
  10. System.out.println("环绕通知执行后");
  11. }
  12.  
  13. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  9.  
  10. <!-- 目标类 -->
  11. <bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
  12.  
  13. <!-- 切面 -->
  14. <bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
  15.  
  16. <!--
  17. 配置AOP
  18. -->
  19. <aop:config>
  20. <!--
  21. 配置切入点
  22. -->
  23. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
  24. <!--
  25. 配置切面
  26. -->
  27. <aop:aspect ref="transaction">
  28. <!--
  29. 环绕通知
  30. -->
  31. <aop:around method="aroundMethod" pointcut-ref="pointcut" />
  32.  
  33. </aop:aspect>
  34.  
  35. </aop:config>
  36.  
  37. </beans>
  • 示例:一个切入点跟多个切面
  1. package com.xuweiwei;
  2. public interface PersonDao {
  3.  
  4. public void savePerson();
  5.  
  6. }
  1. package com.xuweiwei;
  2.  
  3. /**
  4. * 目标类
  5. */
  6. public class PersonDaoImpl implements PersonDao {
  7.  
  8. @Override
  9. public void savePerson() {
  10. System.out.println("保存用户信息");
  11. }
  12. }
  1. package com.xuweiwei;
  2.  
  3. /**
  4. * 切面
  5. */
  6. public class Logger {
  7. /**
  8. * 通知
  9. */
  10. public void logging(){
  11. System.out.println("打印日志");
  12. }
  13. }
  1. package com.xuweiwei;
  2. /**
  3. * 切面
  4. */
  5. public class Transaction {
  6. /**
  7. * 通知
  8. */
  9. public void beginTransaction(){
  10. System.out.println("开启事务");
  11. }
  12. /**
  13. * 通知
  14. */
  15. public void commit(){
  16. System.out.println("提交事务");
  17. }
  18.  
  19. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  9. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
  10. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
  11.  
  12. <!--
  13. 目标类
  14. -->
  15. <bean id="personDao" class="com.xuweiwei.PersonDaoImpl"></bean>
  16.  
  17. <!--
  18. 切面
  19. -->
  20. <bean id="transaction" class="com.xuweiwei.Transaction"></bean>
  21. <!--
  22. 切面
  23. -->
  24. <bean id="logger" class="com.xuweiwei.Logger"></bean>
  25.  
  26. <!-- -->
  27. <aop:config>
  28. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.PersonDaoImpl.*(..) )"/>
  29. <aop:aspect ref="logger">
  30. <aop:before method="logging" pointcut-ref="pointcut"/>
  31. </aop:aspect>
  32. <aop:aspect ref="transaction">
  33. <aop:before method="beginTransaction" pointcut-ref="pointcut"/>
  34. <aop:after method="commit" pointcut-ref="pointcut" />
  35. </aop:aspect>
  36. </aop:config>
  37.  
  38. </beans>
  1. package com.xuweiwei;
  2.  
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. public class Test {
  7. @org.junit.Test
  8. public void test(){
  9. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  10. PersonDao personDao = (PersonDao) context.getBean("personDao");
  11. personDao.savePerson();
  12.  
  13. }
  14.  
  15. }

6 xml方式的AOP的案例---使用Spring AOP进行异常处理(对所有的service进行异常处理)

  • dao层

    • PersonDAO.java  
  1. package com.xuweiwei.exception.dao;
  2.  
  3. public interface PersonDAO {
  4.  
  5. public void savePerson() throws Exception;
  6.  
  7. }
    • PersonDAOImpl.java  
  1. package com.xuweiwei.exception.dao.impl;
  2.  
  3. import com.xuweiwei.exception.dao.PersonDAO;
  4.  
  5. public class PersonDAOImpl implements PersonDAO{
  6.  
  7. @Override
  8. public void savePerson() throws Exception {
  9. int a = 1/ 0;
  10. }
  11. }
  • service层

    • PersonService.java  
  1. package com.xuweiwei.exception.service;
  2.  
  3. public interface PersonService {
  4.  
  5. public void savePerson() throws Exception;
  6.  
  7. }
    • PersonServiceImpl.java  
  1. package com.xuweiwei.exception.service.impl;
  2.  
  3. import com.xuweiwei.exception.dao.PersonDAO;
  4. import com.xuweiwei.exception.service.PersonService;
  5.  
  6. public class PersonServiceImpl implements PersonService {
  7.  
  8. private PersonDAO personDAO;
  9.  
  10. public PersonDAO getPersonDAO() {
  11. return personDAO;
  12. }
  13.  
  14. public void setPersonDAO(PersonDAO personDAO) {
  15. this.personDAO = personDAO;
  16. }
  17.  
  18. @Override
  19. public void savePerson() throws Exception {
  20. personDAO.savePerson();
  21. }
  22. }
  • action

    • PersonAction.java  
  1. package com.xuweiwei.exception.action;
  2.  
  3. import com.xuweiwei.exception.service.PersonService;
  4.  
  5. public class PersonAction {
  6. private PersonService personService;
  7.  
  8. public PersonService getPersonService() {
  9. return personService;
  10. }
  11.  
  12. public void setPersonService(PersonService personService) {
  13. this.personService = personService;
  14. }
  15.  
  16. public void savePerson(){
  17.  
  18. try {
  19. this.personService.savePerson();
  20. } catch (Exception e) {
  21. throw new RuntimeException(e);
  22. }
  23.  
  24. }
  25.  
  26. }
  • aspect(异常切面)

    • ExceptionAspect.java  
  1. package com.xuweiwei.exception.aspect;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4.  
  5. import javax.servlet.http.HttpServletResponse;
  6.  
  7. //异常的切面
  8. public class ExceptionAspect {
  9.  
  10. //处理异常的通知
  11. public void hanleException(JoinPoint joinPoint, Throwable ex){
  12. printLog(ex);
  13.  
  14. }
  15.  
  16. private void printLog(Throwable ex) {
  17.  
  18. }
  19.  
  20. }
  • applicationContext.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  9.  
  10. <!-- dao -->
  11. <bean id="personDAO" class="com.xuweiwei.exception.dao.impl.PersonDAOImpl"/>
  12.  
  13. <!-- service -->
  14. <bean id="personService" class="com.xuweiwei.exception.service.impl.PersonServiceImpl">
  15. <property name="personDAO" ref="personDAO"/>
  16. </bean>
  17.  
  18. <bean id="personAction" class="com.xuweiwei.exception.action.PersonAction">
  19. <property name="personService" ref="personService"/>
  20. </bean>
  21.  
  22. <!-- 切面 -->
  23. <bean id="aspect" class="com.xuweiwei.exception.aspect.ExceptionAspect"></bean>
  24.  
  25. <aop:config>
  26. <aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.exception.service.*.*(..))"/>
  27. <aop:aspect ref="aspect">
  28. <aop:after-throwing method="hanleException" throwing="ex" pointcut-ref="pointcut"/>
  29. </aop:aspect>
  30.  
  31. </aop:config>
  32.  
  33. </beans>
  • 测试
  1. package com.test;
  2.  
  3. import com.xuweiwei.exception.action.PersonAction;
  4. import org.junit.Test;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;
  7.  
  8. public class TestException {
  9.  
  10. @Test
  11. public void test(){
  12. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  13. PersonAction personAction = (PersonAction) context.getBean("personAction");
  14. personAction.savePerson();
  15.  
  16. }
  17.  
  18. }

7 注解方式的AOP

  • 步骤:

    • ①在applicationContext.xml中设置如下信息  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  9. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
  10. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
  11.  
  12. <context:component-scan base-package="com.xuweiwei"/>
  13.  
  14. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  15.  
  16. </beans>
    • ②在切面类中设置@Component和@Aspect,以及切入点,请看下面  
  1. package com.xuweiwei;
  2.  
  3. import org.aspectj.lang.annotation.After;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Before;
  6. import org.aspectj.lang.annotation.Pointcut;
  7. import org.springframework.stereotype.Component;
  8.  
  9. /**
  10. * 切面
  11. */
  12. @Component
  13. @Aspect //此注解表明这是一个切面
  14. public class Transaction {
  15.  
  16. //设置切入点
  17. @Pointcut("execution( * com.xuweiwei.PersonDaoImpl.*(..))")
  18. private void pointcut(){}
  19.  
  20. /**
  21. * 设置前置通知
  22. */
  23. @Before("pointcut()")
  24. public void beginTransaction(){
  25. System.out.println("开启事务");
  26. }
  27. /**
  28. * 设置最终通知
  29. */
  30. @After("pointcut()")
  31. public void commit(){
  32. System.out.println("提交事务");
  33. }
  34.  
  35. }
  1. package com.xuweiwei;
  2.  
  3. import org.aspectj.lang.annotation.After;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Pointcut;
  6. import org.springframework.stereotype.Component;
  7.  
  8. /**
  9. * 切面
  10. */
  11. @Component
  12. @Aspect
  13. public class Logger {
  14.  
  15. //设置切入点
  16. @Pointcut("execution(* com.xuweiwei.PersonDaoImpl.*(..))")
  17. private void pointcut(){}
  18.  
  19. /**
  20. * 设置前置通知
  21. */
  22. @After("pointcut()")
  23. public void logging(){
  24. System.out.println("打印日志");
  25. }
  26. }
    • 目标类实现的接口和目标类  
  1. package com.xuweiwei;
  2. public interface PersonDao {
  3.  
  4. public void savePerson();
  5.  
  6. }
  1. package com.xuweiwei;
  2.  
  3. import org.springframework.stereotype.Component;
  4.  
  5. /**
  6. * 目标类
  7. */
  8. @Component("personDao")
  9. public class PersonDaoImpl implements PersonDao {
  10.  
  11. @Override
  12. public void savePerson() {
  13. System.out.println("保存用户信息");
  14. }
  15. }
    • 测试    
  1. package com.xuweiwei;
  2.  
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. public class Test {
  7. @org.junit.Test
  8. public void test(){
  9. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  10. PersonDao personDao = (PersonDao) context.getBean("personDao");
  11. personDao.savePerson();
  12.  
  13. }
  14.  
  15. }

Spring 4.x (二)的更多相关文章

  1. spring boot / cloud (二) 规范响应格式以及统一异常处理

    spring boot / cloud (二) 规范响应格式以及统一异常处理 前言 为什么规范响应格式? 我认为,采用预先约定好的数据格式,将返回数据(无论是正常的还是异常的)规范起来,有助于提高团队 ...

  2. Spring Data(二)查询

    Spring Data(二)查询 接着上一篇,我们继续讲解Spring Data查询的策略. 查询的生成 查询的构建机制对于Spring Data的基础是非常有用的.构建的机制将截断前缀find-By ...

  3. spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求

    spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求 有半年多没有更新了,按照常规剧本,应该会说项目很忙,工作很忙,没空更新,吧啦吧啦,相关的话吧, 但是细想想 ...

  4. Spring IOC(二)容器初始化

    本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 一.ApplicationContext接 ...

  5. 深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...

  6. spring AOP 之二:@AspectJ注解的3种配置

    @AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...

  7. Spring Boot 2 (二):Spring Boot 2 动态 Banner

    Spring Boot 2 (二):Spring Boot 2 动态 Banner Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner. 一.配置依赖 使用 Sp ...

  8. Spring Boot(十二):spring boot如何测试打包部署

    Spring Boot(十二):spring boot如何测试打包部署 一.开发阶段 1,单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. (1)在p ...

  9. (转)Spring Cloud(二)

    (二期)23.微服务框架spring cloud(二) [课程23]熔断器-Hystrix.xmind0.1MB [课程23]微服务...zuul.xmind0.2MB 熔断器-Hystrix 雪崩效 ...

  10. spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关)

    spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关) zuul: routes: #路由配置表示 myroute1: #路由名一 path: ...

随机推荐

  1. dict-命令行下中英文翻译工具

    命令行下中英文翻译工具(Chinese and English translation tools in the command line) 安装(Install) ubuntu 安装 pip sud ...

  2. CentOS7卸载自带jdk安装自己的JDK1.8

    1.查看centos自带的jdk rpm -qa | grep Java 2.删除自带的jdk 例如:rpm -e --nodeps java-1.8.0-openjdk-1.8.0.102-4.b1 ...

  3. C# 获取当前方法的名称空间、类名和方法名称

    1.(new StackTrace()).GetFrame(1) // 0为本身的方法:1为调用方法2.(new StackTrace()).GetFrame(1).GetMethod().Name; ...

  4. Redux 介绍

    本文主要是对 Redux 官方文档 的梳理以及自身对 Redux 的理解. 单页面应用的痛点 对于复杂的单页面应用,状态(state)管理非常重要.state 可能包括:服务端的响应数据.本地对响应数 ...

  5. Open Judge 2750 鸡兔同笼

    2750:鸡兔同笼                                                                                            ...

  6. HDU 1847 Good Luck in CET-4 Everybody!(规律,博弈)

    Good Luck in CET-4 Everybody! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  7. linux 操作系统/xxx目录下都是什么文件?

    /bin:存放最常用命令: /dev:设备文件: /etc:存放各种配置文件: /home:用户主目录: /lib:系统最基本的动态链接共享库: /mnt:一般是空的,用来临时挂载别的文件系统: /b ...

  8. c++(排序二叉树线索化)

    前面我们谈到了排序二叉树,还没有熟悉的同学可以看一下这个,二叉树基本操作.二叉树插入.二叉树删除1.删除2.删除3.但是排序二叉树也不是没有缺点,比如说,如果我们想在排序二叉树中删除一段数据的节点怎么 ...

  9. java构建学生管理系统(一)

    用java搭建学生管理系统,重要还是对数据库的操作,诸如增删改查等. 1.基本的功能: 老师完成对学生信息的查看和修改,完成对班级的信息的概览. 学生可以看自己的成绩和对自己信息的修改. 学生和老师有 ...

  10. Newbit 启用淘宝店域名

    自2016-10-19起,我们正式启用淘宝店的域名,newbit.taobao.com 店里提供所有课程当中用到硬件,ZigBee插件/贴片模块等, 我们将坚持给大家提供最具扩展性,最方便使用的开发工 ...