两种类型AOP:静态AOP和动态AOP。
静态代理:
代理对象与被代理对象必须实现同一个接口。
demo:
-
packagecn.partner4java.proxy.staticproxy;
-
-
-
-
-
-
-
-
publicinterfaceIHello
{
-
-
-
-
-
publicvoidhello(String
name);
-
}
-
packagecn.partner4java.proxy.staticproxy;
-
-
-
-
-
-
-
publicclassHelloSpeakerimplementsIHello
{
-
-
publicvoidhello(String
name) {
-
System.out.println("Hello
"+
name);
-
}
-
-
}
-
packagecn.partner4java.proxy.staticproxy;
-
-
-
-
-
publicclassHelloProxyimplementsIHello
{
-
-
privateIHello
iHello;
-
-
publicHelloProxy(IHello
iHello) {
-
super();
-
this.iHello
= iHello;
-
}
-
-
-
publicvoidhello(String
name) {
-
System.out.println("记录日志");
-
iHello.hello(name);
-
}
-
-
}
-
packagecn.partner4java.proxy.staticproxy;
-
-
-
-
-
-
-
publicclassProxyDemo
{
-
-
publicstaticvoidmain(String[]
args) {
-
IHello
iHello =newHelloProxy(newHelloSpeaker());
-
iHello.hello("long");
-
}
-
-
}
动态代理:
动态代理区别于静态带来实现的地方在于织入过程是在运行时动态进行的。自己实现一般实现java.lang.reflect.InvocationHandler接口。
例子:
-
packagecn.partner4java.proxy.dynamicproxy;
-
-
-
publicinterfaceIHello
{
-
publicvoidhello(String
name);
-
}
-
packagecn.partner4java.proxy.dynamicproxy;
-
-
-
-
-
-
-
publicclassHelloSpeakerimplementsIHello
{
-
-
publicvoidhello(String
name) {
-
System.out.println("Hello
"+
name);
-
}
-
-
}
-
packagecn.partner4java.proxy.dynamicproxy;
-
-
importjava.lang.reflect.InvocationHandler;
-
importjava.lang.reflect.Method;
-
importjava.lang.reflect.Proxy;
-
-
-
-
-
-
-
publicclassLogHandlerimplementsInvocationHandler
{
-
-
privateObject
delegate;
-
-
publicObject
bind(Object delegate){
-
this.delegate
= delegate;
-
returnProxy.newProxyInstance(delegate.getClass().getClassLoader(),
-
delegate.getClass().getInterfaces(),this);
-
}
-
-
-
-
publicObject
invoke(Object proxy, Method method, Object[] args)
-
throwsThrowable
{
-
Object
result =null;
-
try{
-
System.out.println("添加日志");
-
result
= method.invoke(delegate, args);
-
}catch(Exception
e) {
-
e.printStackTrace();
-
}
-
-
returnnull;
-
}
-
-
}
-
packagecn.partner4java.proxy.dynamicproxy;
-
-
-
-
-
-
-
publicclassProxyDemo
{
-
publicstaticvoidmain(String[]
args) {
-
LogHandler
logHandler =newLogHandler();
-
IHello
iHello = (IHello) logHandler.bind(newHelloSpeaker());
-
iHello.hello("long");
-
}
-
}
------------------------------------------------------------------
利用ProxyFactory连接CGLIB简单实现AOP:
加入包aopalliance.jar\cglib-nodep-2.1_3.jar
demo:
-
packagecn.partner4java.proxy.proxyfactory;
-
-
-
-
-
-
-
publicclassMessageWriter
{
-
publicvoidwriteMessage(){
-
System.out.println("world!");
-
}
-
}
-
packagecn.partner4java.proxy.proxyfactory;
-
-
importorg.aopalliance.intercept.MethodInterceptor;
-
importorg.aopalliance.intercept.MethodInvocation;
-
-
-
-
-
-
-
-
publicclassMessageDecoratorimplementsMethodInterceptor{
-
-
publicObject
invoke(MethodInvocation invocation)throwsThrowable
{
-
System.out.print("Hello
");
-
Object
retVal = invocation.proceed();
-
returnretVal;
-
}
-
-
}
-
packagecn.partner4java.proxy.proxyfactory;
-
-
importorg.springframework.aop.framework.ProxyFactory;
-
-
-
-
-
-
-
-
publicclassHelloWorldWeaver
{
-
-
publicstaticvoidmain(String[]
args) {
-
-
MessageWriter
target =newMessageWriter();
-
-
-
ProxyFactory
proxyFactory =newProxyFactory();
-
-
proxyFactory.addAdvice(newMessageDecorator());
-
proxyFactory.setTarget(target);
-
-
-
MessageWriter
proxy = (MessageWriter) proxyFactory.getProxy();
-
-
target.writeMessage();
-
System.out.println("---");
-
proxy.writeMessage();
-
-
-
-
-
}
-
-
}
------------------------------------------------------------------
代理
1.代理解决什么问题,为已存在的目标类的方法增加一些系统功能。如果采用工厂模式和配置文件进行管理,以后也很容易就可以去掉增加的功能。
2.静态代理类的工作原理,太多静态代理类,还有什么意思?jvm可以帮我们创建代理类,这就是动态代理类。
3.让jvm创建动态代理类,我们需要给它提供哪些信息?
让jvm帮我们创建一个类,我们需要为它提供哪些信息呢?a.有哪些方法,即告诉它实现哪些接口;b.产生的类必须有个妈妈,即类加载器对象;c.它生成的类中的方法的代码是怎样的,需我告诉它,我把我的代码写在一个约定好了接口的对象的方法中,把对象传给它,它调用我的方法,即相当于插入了我的代码。
4.写程序的步骤:
1). 快速演示动态代理的效果
-
privatestaticvoidtest1()
{
-
Collection
proxy = (Collection)Proxy.newProxyInstance(
-
ProxyTest.class.getClassLoader(),
-
newClass[]{Collection.class}
,
-
newInvocationHandler(){
-
Vector
target =newVector();
-
@Override
-
publicObject
invoke(Object proxy, Method method,
-
Object[]
args)throwsThrowable
{
-
-
System.out.println("begin
"+
method.getName());
-
Object
retval = method.invoke(target, args);
-
System.out.println("end"+
method.getName());
-
returnretval;
-
}
-
-
}
-
);
-
-
System.out.println(proxy.getClass().getName());
-
proxy.add("abc");
-
proxy.add("xyz");
-
System.out.println(proxy.size());
-
-
}
2).可以接收外面传入的目标
-
privatestaticvoidtest2()
{
-
Vector
v =newVector();
-
classMyInvocationHandlerimplementsInvocationHandler
-
{
-
Collection
target =null;
-
-
publicMyInvocationHandler(){}
-
publicMyInvocationHandler(Collection
target){this.target
= target;}
-
@Override
-
publicObject
invoke(Object proxy, Method method,
-
Object[]
args)throwsThrowable
{
-
-
System.out.println("begin
"+
method.getName());
-
Object
retval = method.invoke(target, args);
-
System.out.println("end"+
method.getName());
-
returnretval;
-
}
-
-
}
-
-
Collection
proxy1 = (Collection)Proxy.newProxyInstance(
-
ProxyTest.class.getClassLoader(),
-
newClass[]{Collection.class}
,
-
newMyInvocationHandler(v));
-
-
System.out.println(proxy1.getClass().getName());
-
proxy1.add("abc");
-
proxy1.add("xyz");
-
System.out.println(proxy1.size());
-
}
3).最优雅的方式,接收目标同时返回代理,让调用者更懒惰,更方便,调用者甚至不用接触任何代理的API。
-
privatestaticvoidtest3()
{
-
Vector
v =newVector();
-
classMyInvocationHandlerimplementsInvocationHandler
-
{
-
Collection
target =null;
-
-
publicCollection
bind(Collection target)
-
{
-
this.target
= target;
-
Collection
proxy1 = (Collection)Proxy.newProxyInstance(
-
ProxyTest.class.getClassLoader(),
-
newClass[]{Collection.class}
,
-
this);
-
returnproxy1;
-
}
-
@Override
-
publicObject
invoke(Object proxy, Method method,
-
Object[]
args)throwsThrowable
{
-
-
System.out.println("begin
"+
method.getName());
-
Object
retval = method.invoke(target, args);
-
System.out.println("end"+
method.getName());
-
returnretval;
-
}
-
-
}
-
MyInvocationHandler
handler =newMyInvocationHandler();
-
Collection
proxy1 = handler.bind(v);
-
-
System.out.println(proxy1.getClass().getName());
-
proxy1.add("abc");
-
proxy1.add("xyz");
-
System.out.println(proxy1.size());
-
}
一点小心得:静态方法中也可以定义内部类,只是内部类中不能方法外部类的成员变量。
-
iterface
Foo
-
{
-
doTest();
-
}
-
-
Class
xxx = Proxy.getProxyClass(Foo.class.getClassLoader(),Class
[] {Foo.class});
-
Proxy方法自动生成一个类的字节码,这个自动生成的类实现了Foo接口(可以实现若干接口)。生成的类有Foo接口中的所有方法和一个如下形式的构造方法:
-
Xxx
-
{
-
InvocationHandler
handler;
-
publicXxx(InvocationHandler
handler)
-
{
-
this.handler
= handler;
-
}
-
-
doTest()
-
{
-
handler.invoke(this,newMethod("doTest"),null)
-
}
-
}
-
-
创建代理类的实例对象的语法解释
-
clsProxy.getConstructor(Class
[]{InvocationHandlre.class}).newInstance(xhandlder);
-
Invocationhandler接口的实现示意:
-
classMyInvocationHandler
impments InvocationHandler
-
{
-
invoke(Object
proxy,Method method,Object[] args)
-
{
-
log.info();
-
Mehtod.invoke(yyy);
-
}
-
}
分享到:
相关推荐
java static proxy dynamic proxy
package cn.sxt.dynamicproxy; import java.util.ArrayList; import java.util.List; import cn.sxt.service.UserService; import cn.sxt.service.UserServiceImpl; public class Client { public ...
basicKnowledge.dynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /* * JDK 动态代理 * */ public class dynamicProxyUsingJDK { ...
因为程序里面有个静态方法,如果导入import static java.lang.Integer.parseInt;这样的程序就可以运行了。 2.可变参数与for循环增强 这个是一般的用法: public static void loop(String[] args){ for(int i=0;i;i++...
设计模式之 Proxy(代理) 以 Jive 为例,剖析代理模式在用户级别授权机制上的应用 设计模式之 Facade(门面?) 可扩展的使用 JDBC针对不同的数据库编程,Facade提供了一种灵活的实现. 设计模式之 Composite(组合) ...
0 Logical Routers 38 4.2.3 Fully Distributed Two Tier Routing 39 4.3 Edge Node 41 4.3.1 Bare Metal Edge 42 4.3.2 VM Form Factor 46 4.3.3 Edge Cluster 48 4.4 Routing Capabilities 49 4.4.1 Static ...
Static Controls Dialog Data Exchange Data Exchange Code in Practice Data Validation Code with DDV_ Using ClassWizard Performing Cross-Edits About Live Edits Using Common Dialogs File Save and ...
建立动态地址翻译 ip nat inside source {list {access-list-number | name} pool name [overload] | static local-ip global-ip} 指定内部和外部端口 ip nat {inside | outside} 如下图所示, 路由器的Ethernet ...
通过 RemoteObject 进行调用虽然简单,但存在不少问题:首先,RemoteObject 是一个 Dynamic Class,Flex Builder 的编译器无法替我们检查参数类型和参数个数,这样,在编写 ActionScript 代码时极易出错。...
BlazeDS 将读取 services-config.xml 配置文件,该配置文件又引用了 remoting-config.xml、proxy-config.xml 和 messaging-config.xml 这 3 个配置文件,所以,一共需要 4 个配置文件。 由于 BlazeDS 需要将 Java ...
Creating Proxy Server Resources..................................................................................................... 2-5 Creating Message Format Files ....................................
Dynamic Arrays 191 Functions 192 Object Oriented Programming 196 Inheritance 196 Polymorphism 197 Encapsulation 197 Classes 198 Adding Properties 198 Adding Methods 200 System.Object 201 ...
;;;;;;;;... 1.... 2.... 3.... 4.... 5.... 6.... The syntax of the file is extremely simple.... Section headers (e.g.... at runtime.... There is no name validation.... (e.g.... previously set variable or directive (e.g....
Instantiation with a static factory method .................................................... 30 Spring Framework 4.0.0.RELEASE Spring Framework Reference Documentation iii Instantiation using an ...
Instantiation with a static factory method .................................................... 30 Spring Framework 4.0.0.RELEASE Spring Framework Reference Documentation iii Instantiation using an ...