精华内容
下载资源
问答
  • spring 切面编程实例

    2009-11-26 15:47:39
    spring 切面编程实例 aop spring 切面编程实例 aop
  • C# 面向切面编程实例

    热门讨论 2013-07-16 22:55:05
    C# 面向切面编程实例,有兴趣的朋友可以下载研究!
  • 一下利用Spring4的最后一个版本Spring4.3.9,实现简单的方法拦截实例。 Eclipse 建立java工程,导入必要的jar包,工程目录如下: 下载源码 实体类 服务类 测试类 通知类 beans.xml 运行结果 ...

    一下利用Spring4的最后一个版本Spring4.3.9,实现简单的方法拦截实例。
    Eclipse 建立java工程,导入必要的jar包,工程目录如下:
    下载源码

    在这里插入图片描述
    实体类
    在这里插入图片描述
    服务类
    在这里插入图片描述
    测试类
    在这里插入图片描述
    通知类
    在这里插入图片描述
    beans.xml
    在这里插入图片描述
    运行结果
    在这里插入图片描述

    展开全文
  • 主要介绍了MVC AOP面向切面编程简单介绍及实例的相关资料,需要的朋友可以参考下
  • AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对传统 OOP(Object-Oriented Programming,面向对象编程)的补充,底层是用动态代理实现。怎么理解面向切面变成呢?首先要明确 "切面" 的概念...

    1.AOP怎么样理解?

    AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论、是对传统 OOP(Object-Oriented Programming,面向对象编程)的补充,底层是用动态代理实现。怎么理解面向切面变成呢?首先要明确 "切面" 的概念。切面其实就是一个类,这个类中定义着横切关注点的信息,而横切关注点就是从每个方法中抽取出来的同一类非核心业务的代码。我们合理运用AOP思想编程,可以使我们的业务模块更加简洁,只包含核心业务代码,而且这样做每个事物逻辑位于一个位置,代码不分散便于维护。

    2.AOP术语 

    下面介绍一些aop的常用术语:

    1.横切关注点:从每个方法中抽取出来的同一类非核心业务代码。

    2.切面:封装横切信息点的类,每个关注点体现为一个通知方法。

    3.通知:切面必须要完成的各个具体工作,也就是切面里的一个个方法。

    4.目标:被通知的对象,也就是被通知方法所作用的对象。

    5.代理:像目标对象应用通知之后所创建的代理对象。

    6.连接点:横切关注点在程序代码中的具体体现,对应用程序执行的某个特定位置。(通俗来讲就是一个个的方法)

    7.切入点:切入点就是定位连接点的方式。每个通知上的切入点表达式找到对应的连接点,执行通知之后连接点也就变成了切入点。

    为了更直观理解上述术语的关系,附上一张关系图解图方便大家理解:

    3.AOP的一个实例

    我们直接利用aop的思想来做一个算术计算器的例子来帮助大家理解aop的思想。

    3.1 在编程中我们一般不用Spring自带的aop框架,Java社区里最完整最流行的AOP框架是AspectJ,在Spring2.0以上版本中,可以使用基于AspectJ注解或基于XML配置的AOP。这个实例总体来说就是在每一个计算器的方法前后我们要加上日志管理功能,也就说在程序帮我们计算出结果的同时我们也要看到程序执行了那个方法、计算的参数是什么、以及结果或者异常信息等等。这些功能如果写在一起就会加重我么核心代码的负担,使得我们的代码很繁琐而且利用率不高。所以我们使用aop切面来开发,将一些日志请求的一些功能利用动态代理写到一个代理类中,无论计算器的那个方法被调用,我们的切面类都会根据我们的要求被调用,从而实现我么想要的过程和结果,这样做代码会简单很多,而且利用率会很高。

    3.2搭建开发环境:首先我们新建maven工程,然后在pom.xml文件中导入我们所需要的依赖。

    <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.1</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>compile</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
            <dependency>
                <groupId>com.mchange</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.5.2</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/cglib/cglib -->
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.2.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.13</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
            <dependency>
                <groupId>aopalliance</groupId>
                <artifactId>aopalliance</artifactId>
                <version>1.0</version>
            </dependency>
        </dependencies>

    3.3 编写计算方法接口:里面我们写加减乘除的四个方法用来计算

    public interface ArithmeticCalculator {
    
        public int add(int i, int j);
    
        public int sub(int i, int j);
    
        public int mul(int i, int j);
    
        public int div(int i, int j);
    }

    3.4 编写接口的实现类:实现我们的四个方法。

    需要注意的是:我们实现类需要加入注解@Component,既然我们使用Spring AOP开发,我们就得将这个类加入我们的Sring容器中,这个注解会帮助我们将这个类管理到Spring的IOC容器中,在我们使用的时候可以方便调用。

    @Component
    public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
    
        public int add(int i, int j) {
            int result = i+j;
            return result;
        }
    
        public int sub(int i, int j) {
            int result = i-j;
            return result;
        }
    
        public int mul(int i, int j) {
            int result = i*j;
            return result;
        }
    
        public int div(int i, int j) {
            int result = i/j;
            return result;
        }
    }
    

    3.5 配置我们的xml配置文件:我么基于注解开发和使用AspectJ来开发,就需要在xml文件中配置俩个配置。

    组件扫描是将我们写的类都加入Spring的容器中,让Spring找到对应的注解进行工作。

    <?xml version="1.0" encoding="UTF-8"?>
    <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"
           xmlns:context="http://www.springframework.org/schema/context"
           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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    
        <!--    基于注解开发,必须首先组件扫描-->
        <context:component-scan base-package="com.wei.spring.aspectJ.annotation"></context:component-scan>
    
        <!--    基于注解使用AspectJ  主要的作用是为切面中通知能作用到的目标生成代理-->
        <aop:aspectj-autoproxy/>
    </beans>

    3.6 编写我们的AOP切面:定义好了我们的四个计算方法,我们需要根据我们要实现的需求(在计算方法执行前后都要输出我们想要的日志信息)来进行切面类的编写。

    AOP切面类的一些细节:

         3.6.1 切面类首先要在类前面声明注解@Aspect,将其标注为切面类。因为使用Spring,还需要加@Component注解将其交给Spring容器管理。

         3.6.2 通知:前面也解释了,在切面中就有通知。通知是在具体的连接点上要执行的操作,一个切面可以包括一个或者多个通知,通知所使用的注解的值往往是切入点表达式。通知可分为:前置通知,后置通知,返回通知,异常通知,环绕通知。

                 3.6.2.1 前置通知:在方法执行之前执行的通知,使用@Before注解。

                 3.6.2.2 后置通知:在方法执行之后执行的通知,使用@After注解。后置通知不管目标方法有没有抛出异常,都会执行。但是不能获取方法的结果。

                 3.6.2.3 返回通知:在返回方法正常执行结束之后执行。可以获取到方法的返回值,使用@AfterReturning注解

                 3.6.2.4 异常通知:在目标方法抛出异常之后执行,使用@AfterThrowing注解。获取方法的异常:通过throwing来指定一个名字。必须要与方法的一个形参名一致。

                 3.6.2.5 环绕通知:环绕着目标方法执行,可以理解为是前置,后置,返回,异常通知的结合体,使用@Around注解

        3.6.3 切入点表达式:在通知属性的注解中用value="execution() "来指定。语法格式:execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表])),这样可以精确定位通知要作用到的方法。

                 例如:@Before("execution(public int com.wei.spring.aspectJ.annotation.ArithmeticCalculator.add(int,int))")

                 注意:这样的指定非常局限,我们有时候想定位到整个类的全部方法,或者是方法中不仅仅只有俩个参数等等,我么可以用*来简化表达式。例如:(* com.wei.spring.aspectJ.annotation.*.*(..))。

                 *:任意修饰符,任意返回值

                 *:任意类

     

                 *:任意方法

                 ..:任意参数列表

       3.6.4 当前连接点细节:当前连接点所在方法的方法名、当前传入的参数值等等。这些信息都封装在JoinPoint接口的实例对象中 。   

    下面我们直接上代码:

    @Component 
    @Aspect     
    @Order(1)   
    public class LoggingAspect {
    
        //前置通知:在目标方法(连接点)执行之前执行
    
        @Before("execution(public int com.wei.spring.aspectJ.annotation.ArithmeticCalculator.add(int,int))") 
        public void beforeMethod(JoinPoint joinPoint){
            //获取方法的参数
            Object[] args = joinPoint.getArgs();
            //获取方法名
            String methodName = joinPoint.getSignature().getName();
            System.out.println("前置通知的方法名:"+methodName+","+"方法参数:"+args);
        }
    
        /**
         * 后置通知:在目标方法执行之后执行,不管目标方法有没有抛出异常,都会执行。但是不能获取方法的结果
    
        @After("execution(* com.wei.spring.aspectJ.annotation.*.add(..))")
        public void afterMethod(JoinPoint joinPoint){
            //获取方法名
            String methodName = joinPoint.getSignature().getName();
            System.out.println("后置通知的方法名:"+methodName);
        }
    
        /**
         * 返回通知:再返回方法正常执行结束之后执行。可以获取到方法的返回值
         *
         * 获取方法的返回值:通过returning来指定一个名字,必须要与方法的一个形参一致
         */
        @AfterReturning(value = "execution(* com.wei.spring.aspectJ.annotation.*.add(..))",returning = "result")
        public void afterReturningMethod(JoinPoint joinPoint, Object result){
            //获取方法名
            String methodName = joinPoint.getSignature().getName();
            System.out.println("afterReturning:"+result);
        }
    
        /**
         * 异常通知:在目标方法抛出异常之后执行
         *
         * 获取方法的异常:通过throwing来指定一个名字。必须要与方法的一个形参名一致
         *
         * 可以通过形参中异常的类型来设置抛出指定异常才会执行异常通知
         */
        @AfterThrowing(value = "execution(* com.wei.spring.aspectJ.annotation.*.sub(..))",throwing = "ex")
        public void afterThrowingMethod(JoinPoint joinPoint,Exception ex){
            //获取方法名
            String methodName = joinPoint.getSignature().getName();
            System.out.println("异常通知方法名"+methodName+","+"异常为"+ex);
        }
    
        /**
         * 环绕通知:环绕着目标方法执行,可以理解为是前置,后置,返回,异常通知的结合体
         *           更像是动态代理的全程
         *
         */
    
        @Around(value = "execution(* com.wei.spring.aspectJ.annotation.*.sub(..))")
        public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
    
    
            //执行目标方法
            try {
                //前置通知
                System.out.println("前置通知:");
                Object proceed = proceedingJoinPoint.proceed();
                //返回通知
                System.out.println("返回通知");
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }finally {
                //后置通知:都执行
                System.out.println("后置通知");
    
            }
           return null;
        }
    
    }

    3.7 编写测试类进行测试

    public class test {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext ctx =
                    new ClassPathXmlApplicationContext("spring-aspectJ_annotation.xml");
           
            ArithmeticCalculator ac =
                    ctx.getBean("arithmeticCalculatorImpl", ArithmeticCalculator.class);
    
            System.out.println(ac.getClass().getName());
    
            int add = ac.add(1, 1);
    
            System.out.println(add);
        }
    
    }
    

    运行即可:

    展开全文
  • 最近因为需要开发基于Memcached的一套缓存应用,里面大量运用到了spring aop切面编程,现在提供一个基础实例。 pom文件依赖:    UTF-8  3.1.1.RELEASE   org.springframework spring-core ...

    最近因为需要开发基于Memcached的一套缓存应用,里面大量运用到了spring aop切面编程,现在提供一个基础实例。


    pom文件依赖:

     <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>3.1.1.RELEASE</spring.version>
      </properties>


    <dependencies>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.12</version>
    </dependency>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.12</version>
    </dependency>
    <dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2</version>
    </dependency>
    </dependencies>


    spring bean对象,也是本次需要增强处理的对象:

    @Service
    public class PersonService {


    public void addPerson(String personName) {
    System.out.println("add person " + personName);
    }

    public boolean deletePerson(String personName) {
    System.out.println("delete person " + personName) ;
    return true;
    }

    public void editPerson(String personName) {
    System.out.println("edit person " + personName);
    throw new RuntimeException("edit person throw exception");
    }

    }

    切面Bean定义如下:

    @Component
    @Aspect
    public class SimpleAspect {
    @Pointcut("execution(* com.meiyang.spring.aop.*Service*.*(..))")
    public void pointCut() {
    }


    @After("pointCut()")
    public void after(JoinPoint joinPoint) {
    System.out.println("事后处理after aspect executed");
    }


    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
    //如果需要这里可以取出参数进行处理
    //Object[] args = joinPoint.getArgs();
    System.out.println("事前处理before aspect executing");
    }


    @AfterReturning(pointcut = "pointCut()", returning = "returnVal")
    public void afterReturning(JoinPoint joinPoint, Object returnVal) {
    System.out.println("后面返回afterReturning executed, return result is "
    + returnVal);
    }


    @Around("pointCut()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("之前around start..");
    try {
    pjp.proceed();
    } catch (Throwable ex) {
    System.out.println("error in around");
    throw ex;
    }
    System.out.println("之后around end");
    }


    @AfterThrowing(pointcut = "pointCut()", throwing = "error")
    public void afterThrowing(JoinPoint jp, Throwable error) {
    System.out.println("异常抛出error:" + error);
    }
    }


    新建spring配置文件:appContext.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <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"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                               http://www.springframework.org/schema/aop
                               http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                               http://www.springframework.org/schema/context
                               http://www.springframework.org/schema/context/spring-context-3.1.xsd">
        <aop:aspectj-autoproxy />
        <context:component-scan base-package="com.meiyang.spring.aop" /> 
    </beans>


    下面进行测试:

    public class App 
    {
        public static void main( String[] args )
        {
        ApplicationContext appContext = new FileSystemXmlApplicationContext("e:/appContext.xml");
        PersonService personService = appContext.getBean(PersonService.class);
        String personName = "张国荣";
        personService.addPerson(personName);
    //     personService.deletePerson(personName);
    //     personService.editPerson(personName);


        }
    }


    输出如下:

    事前处理before aspect executing
    之前around start..
    add person 张国荣
    事后处理after aspect executed
    之后around end
    后面返回afterReturning executed, return result is null

    展开全文
  • Java实现AOP面向切面编程实例教程

    千次阅读 2019-03-21 11:31:13
    这篇文章主要介绍了Java实现AOP面向切面编程实例教程,通常Java中的AOP都是利用Spring框架中造好的轮子来开发,而本文则关注于Java本身AOP的设计模式实现,需要的朋友可以参考下 介绍 众所周知,AOP(面向...

    转载自: https://blog.csdn.net/albenxie/article/details/72783301

    这篇文章主要介绍了Java实现AOP面向切面编程的实例教程,通常Java中的AOP都是利用Spring框架中造好的轮子来开发,而本文则关注于Java本身AOP的设计模式实现,需要的朋友可以参考下

    介绍

    众所周知,AOP(面向切面编程)是Spring框架的特色功能之一。通过设置横切关注点(cross cutting concerns),AOP提供了极高的扩展性。那AOP在Spring中是怎样运作的呢?当你只能使用core java,却需要AOP技术时,这个问题的解答变得极为关键。不仅如此,在高级技术岗位的面试中,此类问题也常作为考题出现。这不,我的朋友最近参加了一个面试,就被问到了这样一个棘手的问题——如何在不使用Spring及相关库,只用core Java的条件下实现AOP。因此,我将在本文中提供一份大纲,帮助大家了解如何只用core Java实现一个AOP(当然啦,这种AOP在功能上有一定的局限性)。注意,本文不是一篇有关Spring AOP与Java AOP的对比研究,而是有关在core Java中借助固有的设计模式实现AOP的教程。

    想必读者已经知道AOP是什么,也知道在Spring框架中如何使用它,因此本文只着眼于如何在不用Spring的前提下实现AOP。首先,我们得知道,Spring是借助了JDK proxy和CGlib两种技术实现AOP的。JDK dynamic proxy提供了一种灵活的方式来hook一个方法并执行指定的操作,但执行操作时得有一个限制条件:必须先提供一个相关的接口以及该接口的实现类。实践出真知,让我们透过一个案例来理解这句吧!现在有一个计算器程序,用于完成一些数学运算。让我们来考虑下除法功能,此时的问题是:如果core framework 已经具备了一份实现除法的代码,我们能否在代码执行时劫持(highjack)它并执行额外的校验呢?答案是肯定的,我将用下面提供的代码片段来证明这点。首先来看基础接口的代码:

    public interface Calculator {
    	public int calculate( int a , int b);
    }
    

    该接口实现类的代码如下:

    public class CalculatorImpl implements Calculator {
    	@Override
    	public int calculate(int a, int b) {
    		return a/b;
    	}
    }
    

    假设我们既不能修该上面的代码,也不能对核心库进行任何改动,怎样才能完美地实现校验功能呢?不如试下JDK dynamic proxy的功能吧。

    public class SomeHandler implements InvocationHandler {
        private Object targetObject;
        // Code omitted for simplicity…
        public SomeHandler(Object targetObject) {
            this.targetObject = targetObject;
        }
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
    		// Your complex business validation and logic
    		Object result = method.invoke(targetObject ,params);
    		return result;
    	}
    }
    

    让我们通过测试类来看看由JDK dynamic proxy实现的校验功能的效果如何。

    public static void main(String[] args) {
    	CalculatorImpl calcImpl = new CalculatorImpl();
    	Calculator proxied = (Calculator)ProxyFactory.getProxy (Calculator.class, calcImpl, 
    	    new SomeHandler(calcImpl));
    	int result = proxied.calculate(20, 10);
    	System.out.println("FInal Result :::" + result);
    }
    

    从结果可以看出,简单地实现功能强大的InvocationHandler接口,我们便能得到一个hooking implementation。按照JDK文档的描述,InvocationHandler接口是借助一个代理实例(proxy instance)来处理一个方法调用的。

    现在我们已经知道,InvocationHandler的invoke()方法能够帮助我们解决问题。那么再来解决一个新问题——怎样才能在方法执行的前后执行操作呢?说的更具体一些,我们能通过添加多个aop(before、after、around)来hook一个方法吗(译注:原文为add multiple aops,但我认为Handler是充当Aspect的角色)?答案同样是肯定的。按照以下的步骤建立一个精简的代码模板便能满足这样的需求:

    • 创建一个抽象类,用于将aop应用于目标对象上。
    • 创建名为BeforeHandler 和 AfterHandler的两个aop。前者在方法执行之前工作,而后者则在方法执行结束后工作。
    • 创建一个代理类,使所有的aop handler和目标对象只需作为参数传入,就能创建一个hook。
    • 加入你自己的业务逻辑或者横切关注点。
    • 最后,通过传入相关的参数创建代理对象(proxy object)。

    两种实现AOP的方式: 

    1. JDK提供的动态代理实现

    接口
    public interface UserBean { 
    	void getUser(); 
    	void addUser(); 
    	void updateUser(); 
    	void deleteUser(); 
    } 
    
    原始实现类
    public class UserBeanImpl implements UserBean { 
    	private String user = null; 
    	
    	public UserBeanImpl() {     
    	}   
    	
    	public UserBeanImpl(String user) { 
    		this.user = user; 
    	}   
    	
    	public String getUserName() { 
    		return user; 
    	}   
    	
    	public void getUser() { 
    		System.out.println("this is getUser() method!"); 
    	} 
    	
    	public void setUser(String user) { 
    		this.user = user; 
    		System.out.println("this is setUser() method!"); 
    	} 
    	
    	public void addUser() { 
    		System.out.println("this is addUser() method!"); 
    	} 
    	
    	public void updateUser() { 
    		System.out.println("this is updateUser() method!"); 
    	} 
    	  
    	public void deleteUser() { 
    		System.out.println("this is deleteUser() method!");  
    	}     
    } 
    
    代理类
    import java.lang.reflect.InvocationHandler; 
    import java.lang.reflect.Method; 
    import java.lang.reflect.Proxy; 
    import com.cignacmc.finance.bean.UserBeanImpl; 
     
    public class UserBeanProxy implements InvocationHandler { 
    	private Object targetObject; 
    
    	public UserBeanProxy(Object targetObject) { 
    		this.targetObject = targetObject;     
    	} 
    
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    		UserBeanImpl userBean = (UserBeanImpl) targetObject; 
    		String userName = userBean.getUserName(); 
    		Object result = null; 
    
    		//权限判断 
    		if(userName != null && !"".equals(userName)) { 
    		result = method.invoke(targetObject, args); 
    		} 
    		return result; 
    	} 
    } 
    
    测试类
    import java.lang.reflect.Proxy; 
     
    import com.cignacmc.finance.bean.UserBean; 
    import com.cignacmc.finance.bean.UserBeanImpl; 
    import com.cignacmc.finance.proxy.UserBeanProxy; 
     
    public class ProxyExe { 
    	public static void main(String[] args) { 
    		System.out.println("Proved............."); 
    		UserBeanImpl targetObject = new UserBeanImpl("Bob Liang");    
    		UserBeanProxy proxy = new UserBeanProxy(targetObject); 
    		//生成代理对象     
    		UserBean object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
    			targetObject.getClass().getInterfaces(), proxy); 
    		object.addUser(); 
    
    		System.out.println("NO Proved............."); 
    		targetObject = new UserBeanImpl();    
    		proxy = new UserBeanProxy(targetObject); 
    		//生成代理对象     
    		object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
    			targetObject.getClass().getInterfaces(), proxy); 
    		object.addUser(); 
    	} 
    } 
    

    输出:

    Proved............. 
    this is addUser() method! 
    NO Proved............. 
    

    从上面这个例子可以成功拦截了调用的方法addUser()并对其做了相应的处理

    2. 通过cglib创建代理类

    好处是不要求我们的目标对象实现接口  

    原始类
    public class ClientBean { 
    	private String name = null; 
     
    	public ClientBean() { 
    	
    	} 
     
    	public ClientBean(String name) { 
    		this.name = name; 
    	} 
     
    	public void addClient() { 
    		System.out.println("this is addClient() method!"); 
    	} 
     
    	public void deleteClient() { 
    		System.out.println("this is deleteClient() method!"); 
    	} 
     
    	public void getClient() {
    		System.out.println("this is getClient() method!"); 
    	} 
     
    	public void updateClient() { 
    		System.out.println("this is updateClient() method!"); 
    	} 
     
    	public String getClientName() { 
    		return name; 
    	} 
     
    	public void setClientName(String name) { 
    		this.name = name; 
    	} 
    } 
    
    代理类
    import java.lang.reflect.Method; 
     
    import com.cignacmc.finance.bean.ClientBean; 
     
    import net.sf.cglib.proxy.Enhancer; 
    import net.sf.cglib.proxy.MethodInterceptor; 
    import net.sf.cglib.proxy.MethodProxy; 
     
    public class CGLibProxy implements MethodInterceptor { 
    	private Object targetObject; 
    	
    	public Object createProxyObject(Object targetObject) { 
    		this.targetObject = targetObject; 
    		Enhancer enhancer = new Enhancer(); 
    		enhancer.setSuperclass(this.targetObject.getClass()); 
    		enhancer.setCallback(this); 
    		return enhancer.create(); 
    	} 
    
    	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { 
    		ClientBean clientBean = (ClientBean)targetObject; 
    		String userName = clientBean.getClientName(); 
    		Object result = null; 
    	
    		if(userName != null && !"".equals(userName)) { 
    			result = method.invoke(targetObject, args); 
    		} 
    		return result; 
    	} 
    } 
    
    测试类
    import java.lang.reflect.Proxy; 
    
    import com.cignacmc.finance.bean.ClientBean; 
    import com.cignacmc.finance.bean.UserBean; 
    import com.cignacmc.finance.bean.UserBeanImpl; 
    import com.cignacmc.finance.proxy.CGLibProxy; 
    import com.cignacmc.finance.proxy.UserBeanProxy; 
    
    public class ProxyExe { 
    	public static void main(String[] args) {   
    		System.out.println(".............CGLIB Proxy...................."); 
    		System.out.println("Proved...................."); 
    		CGLibProxy cproxy = new CGLibProxy(); 
    		ClientBean clientBean = (ClientBean)cproxy.createProxyObject(new ClientBean("Bob Liang")); 
    		clientBean.addClient(); 
    		
    		System.out.println("NO Proved...................."); 
    		cproxy = new CGLibProxy(); 
    		clientBean = (ClientBean)cproxy.createProxyObject(new ClientBean()); 
    		clientBean.addClient(); 
    	} 
    } 
    

    输出:

    .............CGLIB Proxy.................... 
    Proved.................... 
    this is addClient() method! 
    NO Proved.................... 
    
    展开全文
  • spring Aop 面向切面编程简单实例

    千次阅读 2017-06-14 16:46:41
    最近画了一点时间研究了一下spring的aop,接下来就先直接放源码: 首先创建一个教师Teacher接口:package com.sise.aop; public interface Teacher { public void teach(); }然后是一个教师类:package ...public cl
  • 如果每个方法里都要反复去写是一件很low的事情,但是如果改用切面编程来实现就十分清爽了。 spring中用@Aspect可以定义一个切面类,用@Pointcut定义一个切点表达式方法。Pointcut的execution即是用正则表达式...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,891
精华内容 19,156
关键字:

切面编程实例