模仿spring-aop的功能,利用注解搭建自己的框架。

入JAVA坑7月有余,也尝试自己手动搭建框架,最近对spring aop的这种切面很着迷,为此记录下自己目前搭出来的小小的demo,后续有时间也会继续改进自己的demo。望大神们不吝赐教。

  主要还是运用反射和java自带的代理类。理论知识就不说了,因为我目前也不是很清楚,避免误导,还是避而不谈吧。好了,直接根据代码撸吧。

  结构:

  

  

接口 Person.java
public interface Person {
    void say();
}

接口实现类

Man.java

public class Man implements Person {
    @Override
    public void say() {
        System.out.println("男人say:....");
    }
}

自定义注解

@interface WaterAOP

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Documented
public @interface WaterAOP {
    enum METHOD{before,after,afterthrowing}
    METHOD method() default METHOD.after;
    String Name() default "类全名";
}

自定义注解类

WaterLog.java

public class WaterLog {

    @WaterAOP(Name = "com.water.aop.attempt3.Man",method = WaterAOP.METHOD.after)
    public void afterAction(){
        System.out.println("后置行为");
    }
    @WaterAOP(Name = "com.water.aop.attempt3.Man",method = WaterAOP.METHOD.before)
    public void beforeAction(){
        System.out.println("前置行为");
    }
}

实现自定义代理类(就是在

Proxy.newProxyInstance()方法的第三个参数里做手脚。用了java8的lambda表达式。

ProxyFactory.java

public class ProxyFactory {
    // 维持一个实现接口的被代理的对象,后面改为对象组,由浅入深
    private Person person;
    private WaterLog waterLog;
    private Method beforeMethod=null,afterMethod=null;
    public ProxyFactory(Person person,WaterLog waterLog){
        this.person=person;
        this.waterLog=waterLog;
    }
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(
                person.getClass().getClassLoader(),
                person.getClass().getInterfaces(),
//                第一个参数就是代理者,如果你想对代理者做一些操作可以使用这个参数;
//                第二个就是被执行的方法,
//                第三个是执行该方法所需的参数。
                (Object proxyObj, Method method,Object[] args)->{
                    //如果没有传入aop 直接返回空
                    if(waterLog==null){
                        return null;
                    }
                    Class aop=waterLog.getClass();
                    Class c = person.getClass();
                    // 获取aop类的方法的注解并赋给自定义的一些变量,下面根据这些变量是否有值来确定是否有注解
                    getAnnotation(aop,c);
                    if(beforeMethod!=null){
                        beforeMethod.invoke(waterLog);
                    }
                    // 代理对象执行方法并且获得返回值
                    Object returnValue=method.invoke(person,args);
                    if(afterMethod!=null){
                        afterMethod.invoke(waterLog);
                    }
                    return returnValue;
                }
        );
    }
    private void getAnnotation(Class aop,Class proxy){
        //如果有AOP的类
        if(waterLog!=null){
            // 获取切面类所有的方法
            Method[] methodsAOP=aop.getMethods();
            // 如果切入的日志类的方法不为空
            if(methodsAOP!=null){
                for(Method logMethod:methodsAOP){
                    // 取得WaterLog类的方法上WaterAOP注解
                    WaterAOP waterAOP=logMethod.getAnnotation(WaterAOP.class);
                    if(waterAOP!=null) {
                        // 如果AOP上的注解与传入的类名一致
                        if (proxy.toString().substring(6).equals(waterAOP.Name())) {
                            if (waterAOP.method() == WaterAOP.METHOD.before) {
                                // 赋值 ,后面再执行
                                beforeMethod=logMethod;
                            }else if(waterAOP.method() == WaterAOP.METHOD.after){
                                afterMethod=logMethod;
                            }
                        }
                    }
                }
            }
        }
    }

}

zhuanzi  https://www.cnblogs.com/water-zmh/p/8427877.html

测试类

Test.java (junit是个测试包,也可以直接用main方法)

public class Test {
    @org.junit.Test
    public void waterAOP(){
        Person person=new Man();
        Person proxyPerson=(Person) new ProxyFactory(person,new WaterLog()).getProxyInstance();
        proxyPerson.say();
    }
}

大致的流程就是:传入要被代理的类和自定义的注解类,运用反射获取注解类里方法上的注解属性的值,然后进行比对,再进行相应的操作。

原文地址:https://www.cnblogs.com/shizhijie/p/8428834.html

时间: 2024-08-29 18:42:36

模仿spring-aop的功能,利用注解搭建自己的框架。的相关文章

Spring Aop实例之AspectJ注解配置

http://blog.csdn.net/xiaoxian8023/article/details/17285809 上篇博文<Spring Aop实例之xml配置>中,讲解了xml配置方式,今天来说说AspectJ注解方式去配置spring aop. 依旧采用的jdk代理,接口和实现类代码请参考上篇博文.主要是将Aspect类分享一下: [java] view plaincopy package com.tgb.aop; import org.aspectj.lang.JoinPoint;

【Android数据库优化】利用注解实现SQLite通用框架抽取

在开发Android应用的过程中,少不了要用到SQLite数据库操作,各种增删查改...一般看来,对于不同的实体类的数据库操作,貌似我们只能使用不同的"增删查改"方法来实现,本次的想法就是,能不能抽取出一个通用的框架,使得对于不同的实体类的数据库操作,可以使用同一个接口的实现来做...废话少说,进入正题. 一.普通的数据库操作的实现 现在有一个Book的类,里面有三个成员变量,id,tittle和summary,其中id将会作为主键,且自增.Book代码如下: package com.

Memcached与Spring AOP构建数分布式据库前端缓存框架

由于上一篇有介绍了Memcached缓存,并集群部署,这边我们就不介绍,我们直接介绍Memcached与Spring AOP构建分布式数据库前端缓存框架 一.Java 实现Memcached客户端,实现分布式 (1)需要的jar 1)commons-pool-1.5.6.jar 2)java_memcached-release_2.6.3.jar 3)slf4j-api-1.6.1.jar 4)slf4j-simple-1.6.1.jar (2)Java 实现Memcached客户端代码如下:

Spring Aop的三个注解:@Around,@Before,@After

最近抽时间看了一些aop.好像翻译叫做切片技术.大概也能说明白是什么意思. 其中,有三个注解需要注意,分别是@Around,@Before,@After. 其中 @Around进行切片捕捉,可以捕捉到joinpoint(理解成切片对象方法). 即对方法A进行切片,则A被调用时,执行@Around.@Around可以调用 joinPoint.proceed()实际执行切片对象方法. @Before在切片方法对象实际调用前执行. @After方法在@Around方法之后调用. 注意,如果在Aroun

Spring基础知识之基于注解的AOP

背景概念: 1)横切关注点:散布在应用中多处的功能称为横切关注点 2)通知(Advice):切面完成的工作.通知定了了切面是什么及何时调用. 5中可以应用的通知: 前置通知(Before):在目标方法被调用前调用通知功能. 后置通知(After):在目标方法完成后调用通知,此时不会关系方法输出什么. 返回通知(After-returning):在目标方法成功执行后调用通知. 异常通知(After-throwing):在目标方法抛出异常后调用通知. 环绕通知(Around):通知包裹了被通知的方法

Spring AOP的本质

不用再百科什么AOP了,我先推荐几篇文章或者系列文章:(感谢这些博文的原作者) 0.  Spring AOP 详解   http://pandonix.iteye.com/blog/336873/ 1.  AOP技术基础系列     http://wayfarer.cnblogs.com/articles/241024.html 2.  我对AOP的理解 http://jinnianshilongnian.iteye.com/blog/1474325 3.  Spring AOP本质系列  ht

Spring AOP: Spring之面向方面编程

Spring AOP: Spring之面向方面编程 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层次的对象,而AOP将程序分解成各个方面 或者说 关注点 . 这使得可以模块化诸如事务管理等这些横切多个对象的关注点.(这些关注点术语称作 横切关注点.) Spring的一个关键组件就是AOP框架. Spring IoC容器(BeanFactory 和ApplicationContext)并不依赖于AOP, 这意味着如果你不需要

spring Aop概念

面向切面编程(AOP)通过提供另外一种思考程序结构的途经来弥补面向对象编程(OOP)的不足.在OOP中模块化的关键单元是类(classes),而在AOP中模块化的单元则是切面.切面能对关注点进行模块化,例如横切多个类型和对象的事务管理.(在AOP术语中通常称作横切(crosscutting)关注点.) AOP框架是Spring的一个重要组成部分.但是Spring IoC容器并不依赖于AOP,这意味着你有权利选择是否使用AOP,AOP做为Spring IoC容器的一个补充,使它成为一个强大的中间件

Spring AOP——Spring 中面向切面编程

前面两篇文章记录了 Spring IOC 的相关知识,本文记录 Spring 中的另一特性 AOP 相关知识. 部分参考资料: <Spring实战(第4版)> <轻量级 JavaEE 企业应用实战(第四版)> Spring 官方文档 W3CSchool Spring教程 易百教程 Spring教程 一.AOP--另一种编程思想 1.1 什么是 AOP AOP (Aspect Orient Programming),直译过来就是 面向切面编程.AOP 是一种编程思想,是面向对象编程(