AOP用CGLib更简便、更可控。

动态代理的实现非常优雅。

实体类:

public class SampleClass {

    public String MyFunction1(String input) {

        System.out.println("MyFunction1方法被调用:Hello:" + input);
return "Hello:" + input;
} public String MyFunction2(String input) { System.out.println("MyFunction2方法被调用:Hello:" + input);
return "Hello:" + input;
}
}
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Dispatcher;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.FixedValue;
import net.sf.cglib.proxy.LazyLoader;
import net.sf.cglib.proxy.NoOp;
import net.sf.cglib.proxy.ProxyRefDispatcher; public class CgLibTest { private static String MyName = ""; public static void main(String[] args) { MyName = "王昕"; DoAOP(); Enhancer enhancer1 = EnhancerNoOp();
SampleClass proxy = (SampleClass) enhancer1.create();
String strOutput = proxy.MyFunction2("赵七");
System.out.println("EnhancerNoOp:"+strOutput); Enhancer enhancer2 = EnhancerFixedValue();
SampleClass proxy2 = (SampleClass) enhancer2.create();
String strOutput2 = proxy2.MyFunction2("赵七");
System.out.println("EnhancerFixedValue:"+strOutput2); } private static void DoAOP() {
MyInterceptor cglib = new MyInterceptor();
SampleClass bookCglib = (SampleClass) cglib
.getInstance(new SampleClass());
bookCglib.MyFunction2("张三");
} // 该回调将替代原类的方法实现
private static Enhancer EnhancerFixedValue() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(new FixedValue() {
@Override
public Object loadObject() throws Exception {
//返回 MyName 作为输入参数的;
return new SampleClass().MyFunction2(MyName);
}
});
return enhancer;
} //执行原(Super)类方法
private static Enhancer EnhancerNoOp() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(NoOp.INSTANCE);
return enhancer;
} //延迟加载
private static Enhancer EnhancerLazyLoader() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(new LazyLoader() {
@Override
public Object loadObject() throws Exception {
//return "回调后的返回值";
return new SampleClass().MyFunction2(MyName);
}
});
return enhancer;
} private static Enhancer EnhancerProxyRefDispatcher(final String obj1) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(new ProxyRefDispatcher() {
@Override
public Object loadObject(Object obj2) throws Exception {
return new SampleClass().MyFunction2(obj1 + (String)obj2);
}
});
return enhancer;
} }

AOP拦截模拟类:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class MyInterceptor implements MethodInterceptor {
private Object target; public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
} @Override
// 回调方法
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("拦截前,做些事情");
proxy.invokeSuper(obj, args);
System.out.println("拦截后,再做些事情");
return null; } }

输出:

拦截前,做些事情
MyFunction2方法被调用:Hello:张三
拦截后,再做些事情
MyFunction2方法被调用:Hello:赵七
EnhancerNoOp:Hello:赵七
MyFunction2方法被调用:Hello:王昕
EnhancerFixedValue:Hello:王昕

MethodDelegate

方法委托:  实现类似C#的委托。将方法调用绑定到某个接口的特定方法

    public void testMethodDelegate() throws Exception {
SampleBean bean = new SampleBean();
bean.setValue("Hello cglib!");
BeanDelegate delegate = (BeanDelegate) MethodDelegate.create(bean,
"getValue", BeanDelegate.class);
assertEquals("Hello world!", delegate.getValueFromDelegate2());
} public interface BeanDelegate {
//String getValueFromDelegate1();
String getValueFromDelegate2();
}

BulkBean

使用数组访问bean的访问器方法调用

    public void testBulkBean() throws Exception {
BulkBean bulkBean = BulkBean.create(SampleBean.class,
new String[] { "getValue" }, new String[] { "setValue" },
new Class[] { String.class });
SampleBean bean = new SampleBean();
bean.setValue("Hello world!");
assertEquals(1, bulkBean.getPropertyValues(bean).length);
assertEquals("Hello world!", bulkBean.getPropertyValues(bean)[0]);
bulkBean.setPropertyValues(bean, new Object[] { "Hello cglib!" });
assertEquals("Hello cglib!", bean.getValue());
}
public class SampleBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

JAVA动态代理和方法拦截(使用CGLib实现AOP、方法拦截、委托)的更多相关文章

  1. Java动态代理之JDK实现和CGlib实现

    一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由 业务实现类.业务代理类 两部分组成.业务实现类 负责实现 ...

  2. Java动态代理之JDK实现和CGlib实现(简单易懂)

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6542259.html 一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是 ...

  3. 【转载】Java动态代理之JDK实现和CGlib实现(简单易懂)

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6542259.html 一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是 ...

  4. 详解Java动态代理机制(二)----cglib实现动态代理

    上篇文章的结尾我们介绍了普通的jdk实现动态代理的主要不足在于:它只能代理实现了接口的类,如果一个类没有继承于任何的接口,那么就不能代理该类,原因是我们动态生成的所有代理类都必须继承Proxy这个类, ...

  5. java 动态代理模式(jdk和cglib)

    package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...

  6. Java动态代理实现方式一

    Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理 实现方式一:静态代理 静态代理方式的优点 静态代理方式的缺点 Java动态代理实现方式一:InvocationHandler Ja ...

  7. java动态代理模式

    java动态代理机制详解 Spring的核心AOP的原理就是java的动态代理机制. 在java的动态代理机制中,有两个重要的类或接口: 1.InvocationHandler(Interface): ...

  8. Java动态代理——框架中的应用场景和基本原理

    前言 之前已经用了5篇文章完整解释了java动态代理的原理,本文将会为这个系列补上最后一块拼图,展示java动态代理的使用方式和应用场景 主要分为以下4个部分 1.为什么要使用java动态代理 2.如 ...

  9. Java动态代理与Cglib库

    JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...

  10. Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

    class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...

随机推荐

  1. 784. Letter Case Permutation

    这个题的思想很重要,两种方法 第一种,回溯法 class Solution { public: int sz; vector<string> letterCasePermutation(s ...

  2. 2019.01.04 bzoj2962: 序列操作(线段树+组合数学)

    传送门 线段树基础题. 题意:要求维护区间区间中选择ccc个数相乘的所有方案的和(c≤20c\le20c≤20),支持区间加,区间取负. 由于c≤20c\le20c≤20,因此可以对于每个线段树节点可 ...

  3. win/mac平台搭建ionic开发环境教程(转)

    出处:http://www.ionic-china.com/doc/ionic-winmac.html#preface 前言 ionic中文网为大家准备了绿色版的nodejs和androidSDK以及 ...

  4. abaqus学习笔记-abaqus与umat调用基本原理

    参考: 1.http://ivt-abaqusdoc.ivt.ntnu.no:2080/v6.14/books/sub/default.htm 2.ABAQUS 用户材料子程序开发及应用-杨曼娟 3. ...

  5. IntelliJ IDEA 2017版 编译器使用学习笔记(六) (图文详尽版);IDE快捷键使用

    一.alter + enter使用 应用于很对场景不知道如何操作代码时使用          1.场景一:自动创建函数         调用一个没有的函数的时候,alter+enter,弹出自动创建函 ...

  6. 第29章:MongoDB-索引--全文索引

    ①全文索引 全文索引是用于对长文本检索来使用的,是用正则表达式只能对字符串类型的值进行检索.注意:创建索引是一件比较耗时耗费资源的事情,而全文索引更是耗时更厉害,如果对索引键的内容比较长,需要对内容进 ...

  7. C++的重载流输出运算符

    // 下列代码输出什么?#include <iostream>#include <string>// typedef basic_ostream<char> ost ...

  8. MIT Molecular Biology 笔记6 转录的调控

    视频  https://www.bilibili.com/video/av7973580?from=search&seid=16993146754254492690 教材 Molecular ...

  9. leetcode - [6]Binary Tree Postorder Traversal

    Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary t ...

  10. Maven之java application _HelloWord

    maven  是一个项目构建的一个工具; 一.环境的配置; 1.下载maven 解压放在一个路径下为了好找我们就将该文件放在 D:\javaNew\apache-maven-3.3.9 2.配置本地仓 ...