• Spring笔记4


    1.   不用Aop使用jdk的代理实现拦截,PersonServiceBean要求必须实现接口

    接口
    1 package cn.itcast.service;
    2 
    3 public interface PersonService {
    4 
    5     public abstract void save();
    6 
    7 }
    被拦截的类
     1 package cn.itcast.service.impl;
     2 
     3 import cn.itcast.service.PersonService;
     4 
     5 public class PersonServiceBean implements PersonService {
     6     
     7     
     8     public String name;
     9     
    10     public PersonServiceBean() {
    11     }
    12     
    13     public PersonServiceBean(String name) {
    14         this.name = name;
    15     }
    16 
    17     public void save(){
    18         System.out.println("我是sava方法");
    19     }
    20 
    21     public String getName() {
    22         return name;
    23     }
    24     
    25 }
    代理类 
    2.  如果类没有实现接口使用cglib实现 ,导入.../lib/cglib下的cglib-nodep-2.1_3.jar文件
    代理类
     1 package cn.itcast.aop;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 import cn.itcast.service.impl.PersonServiceBean;
     6 
     7 import net.sf.cglib.proxy.Enhancer;
     8 import net.sf.cglib.proxy.MethodInterceptor;
     9 import net.sf.cglib.proxy.MethodProxy;
    10 
    11 public class CGlibFactory implements MethodInterceptor{
    12     public Object tagetObject;
    13     
    14     public Object createProxyInstance(Object tagetObject){
    15         this.tagetObject = tagetObject;
    16         Enhancer enhancer = new Enhancer();
    17         //指定父类,重写父类的所有非final方法
    18         enhancer.setSuperclass(this.tagetObject.getClass());
    19         //指定回调函数,类实现MethodInterceptor接口
    20         enhancer.setCallback(this);
    21         return enhancer.create();
    22     }
    23 
    24     @Override
    25     public Object intercept(Object proxy, Method method, Object[] args,
    26             MethodProxy methodProxy) throws Throwable {
    27         PersonServiceBean bean = (PersonServiceBean)this.tagetObject;
    28         Object result=null;
    29         if(bean.getName()!=null){
    30             //将方法的调用委派给目标对象
    31             result = methodProxy.invoke(tagetObject, args);
    32         }
    33         return null;
    34     }
    35 }
    测试类
     1 package cn.itcast.test;
     2 
     3 import org.junit.Test;
     4 
     5 import cn.itcast.aop.CGlibFactory;
     6 import cn.itcast.aop.ProxyFactroy;
     7 import cn.itcast.service.PersonService;
     8 import cn.itcast.service.impl.PersonServiceBean;
     9 
    10 public class AopTest {
    11     @Test public void aopTest(){
    12         ProxyFactroy factory = new ProxyFactroy();
    13         //PersonService用接口类,传参的时候用非接口类,传名字的时候正常,不传名字的时候被拦截
    14         PersonService service = (PersonService) factory.createProxyInstance(new PersonServiceBean("xxx"));
    15         service.save();
    16     }
    17     @Test public void aopTest2(){
    18         CGlibFactory factory = new CGlibFactory();
    19         //传名字的时候正常,不传名字的时候被拦截
    20         PersonServiceBean service = (PersonServiceBean) factory.createProxyInstance(new PersonServiceBean("xxx"));
    21         service.save();
    22     }
    23 }

    3.  AOP的概念:

      Aspect(切面):对横切性关注点的一个抽象,比如上面的Factory类

      joinpoint(连接点):指被拦截到的点,在Spring中指方法,比如上面的save方法

      Pointcut(切入点):是指我们要对哪些joinpoint进行拦截的定义

      Advice(通知):指拦截到joinpoint之后要做的事情,通知分为前置通知,后置通知,例外通知,最终通知,环绕通知

      Target(目标对象):代理的目标对象

      Weave(织入):将Aspect应用到target对象并导致Proxy对象创建的过程

      Introduction(引入):在不修改代码的前提下,Introduction可以为类动态的添加一些方法或Field

    4.  使用Spring的aop实现切面编程:

      1)引入aop的jar包

      2)加入命名空间,第5,10行,第11行打开aop注解

     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
     7            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     8            http://www.springframework.org/schema/context 
     9            http://www.springframework.org/schema/context/spring-context-2.5.xsd
    10            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
    11     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    12 </beans>

      3)创建要拦截的bean以及接口

     1 package cn.itcast.service;
     2 
     3 
     4 import java.util.List;
     5 import java.util.Map;
     6 import java.util.Properties;
     7 import java.util.Set;
     8 
     9 public interface PersonService {
    10 
    11     public abstract void save();
    12     public abstract void update();
    13     public abstract String getPeresonName();
    14 }
     1 package cn.itcast.service.imp;
     2 
     3 import cn.itcast.service.PersonService;
     4 
     5 public class PersonServiceBean implements PersonService {
     6     
     7     @Override
     8     public String getPeresonName() {
     9         return "xxx";
    10         
    11     }
    12 
    13     @Override
    14     public void update() {
    15         System.out.println("update");
    16         
    17     }
    18 
    19     @Override
    20     public void save() {
    21         System.out.println("save");
    22         
    23     }
    24     
    25 }

      4)创建切面,切入点,以及前置通知

     1 package cn.itcast.service;
     2 
     3 import org.aspectj.lang.annotation.Aspect;
     4 import org.aspectj.lang.annotation.Before;
     5 import org.aspectj.lang.annotation.Pointcut;
     6 
     7 @Aspect//切面
     8 public class Interceptor {
     9     //切入点,(返回值,然后是包名,类名,方法,参数)*代表任意,..代表所有
    10     @Pointcut("execution(* cn.itcast.service.imp.PersonServiceBean.*(..))")
    11     private void anyWethod(){}//声明一个切入点
    12     
    13     //前置通知,参数为切入点
    14     @Before("anyWethod()")
    15     public void doAcessCheak(){
    16         System.out.println("前置通知");
    17     }
    18     
    19 }

      5)将切面以及bean交给Spring管理

    1 <bean id="myInterceptor" class="cn.itcast.service.Interceptor"></bean>
    2 <bean id="personService" class="cn.itcast.service.imp.PersonServiceBean"></bean>

      6)测试

    ApplicationContext ctr = new ClassPathXmlApplicationContext("beans.xml");
    PersonService personService = (PersonService) ctr.getBean("personService");
    personService.save();

    控制台会输出前置通知的内容,然后输出save方法中的内容

    5.  前置通知

    1 @Before("anyWethod()")
    2     public void doAcessCheck(){
    3         System.out.println("前置通知");
    4     }
    @Before("anyWethod() && args(name)")//表示拦截参数为一个且是String类型的方法
        public void doAcessCheck(String name){
            System.out.println("前置通知"+name);
        }

    6.  后置通知

    1 @AfterReturning("anyWethod()")
    2     public void doAccessCheckAfter(){
    3         System.out.println("后置通知");
    4     }
    1 @AfterReturning(pointcut="anyWethod()" ,returning="result" )//表示拦截返回值为String类型的方法
    2     public void doAccessCheckAfter(String result){
    3         System.out.println("后置通知"+result);
    4     }

    7.  最终通知

    1 @After("anyWethod()")
    2     public void doAfter(){
    3         System.out.println("最终通知");
    4     }

    8  例外通知

    1 @AfterThrowing("anyWethod()")
    2     public void dofterThrowing(){
    3         System.out.println("例外通知");
    4     }
    1 @AfterThrowing(pointcut="anyWethod()",throwing="e")//表示拦截参数为Exception的异常
    2     public void dofterThrowing(Exception e){
    3         System.out.println("例外通知"+e);
    4     }

    9.  环绕通知

    1 @Around("anyWethod()")
    2     public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
    3         System.out.println("进入方法");
    4         Object result =  pjp.proceed();
    5         System.out.println("退出方法");
    6         return result;
    7     }

    10.  用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
     7            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     8            http://www.springframework.org/schema/context 
     9            http://www.springframework.org/schema/context/spring-context-2.5.xsd
    10            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
    11     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    12     <bean id="personService" class="cn.itcast.service.imp.PersonServiceBean"></bean>
    13     <bean id="sapectBean" class="cn.itcast.service.Interceptor"></bean>
    14     <aop:config>
    15         <aop:aspect id="asp" ref="sapectBean">
    16             <aop:pointcut  id="aspCut" expression="execution(* cn.itcast.service.imp.PersonServiceBean.*(..))"/>
    17             <aop:before pointcut-ref="aspCut" method="doAcessCheck"/>
    18             <aop:after-returning pointcut-ref="aspCut" method="doAccessCheckAfter"/>
    19             <aop:after-throwing pointcut-ref="aspCut" method="dofterThrowing"/>
    20             <aop:after pointcut-ref="aspCut" method="doAfter"/>
    21             <aop:around pointcut-ref="aspCut" method="doAround"/>
    22         </aop:aspect>
    23     </aop:config>    
    24 </beans>

    aop

  • 相关阅读:
    jQuery 获取jsp页面中用iframe引入的jsp页面中的值
    spring事务管理
    mysql中将多行数据合并成一行数据
    C语言字符串格式化输出
    gdb无法单步调试
    Linux系统glibc库版本信息查看
    gcc编译命令行依赖库的指定顺序
    HDFS的基础与操作
    搭建Kubernetes容器集群管理系统
    如何在 CentOS 里下载 RPM 包及其所有依赖包
  • 原文地址:https://www.cnblogs.com/fanglove/p/2818489.html
Copyright © 2020-2023  润新知