Spring高级程序设计 5 Spring AOP基础
2011-11-21 17:28
295 查看
1AOP概念
AOP的核心概念:
连接点(jointpoint):一个连接点是一个程序执行过程中的特定点。
通知(advice):在某一特定的连接点处运行的代码成为“通知”。
切入点(pointcut):切入点是用来定义某一个通知该何时执行的一组连接点。
方面(aspect):通知和切入点的组合叫做方面。
织入(weaving):织入是将方面真正的加入程序代码的过程。
目标(target):如果一个对象的执行过程受到某个AOP操作的修改,那么他就叫做一个目标对象,也成为通知对象。
引入(introduction):通过引入,我们可以在一个对象中加入新的方法或者字段,以改变他的结构。
2AOP的类型
两种类型AOP:静态AOP和动态AOP。
静态代理:
代理对象与被代理对象必须实现同一个接口。
demo:
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
静态代理,统一接口
*
@author partner4java
*
*/
public interface IHello
{
/**
* 可以带来的统一方法
* @param name
*/
public void hello(String
name);
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
被代理的对象,需要借助代理对象加入日志
*
@author partner4java
*
*/
public class HelloSpeaker implements IHello
{
public void hello(String
name) {
System.out.println("Hello
" +
name);
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
代理对象,给被代理对象添加日志
*/
public class HelloProxy implements IHello
{
private IHello
iHello;
public HelloProxy(IHello
iHello) {
super();
this.iHello
= iHello;
}
public void hello(String
name) {
System.out.println("记录日志");
iHello.hello(name);
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
调用
*
@author partner4java
*
*/
public class ProxyDemo
{
public static void main(String[]
args) {
IHello
iHello = new HelloProxy(new HelloSpeaker());
iHello.hello("long");
}
}
动态代理:
动态代理区别于静态带来实现的地方在于织入过程是在运行时动态进行的。自己实现一般实现java.lang.reflect.InvocationHandler接口。
例子:
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
public interface IHello
{
public void hello(String
name);
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
/**
*
被代理的对象,需要借助代理对象加入日志
*
@author partner4java
*
*/
public class HelloSpeaker implements IHello
{
public void hello(String
name) {
System.out.println("Hello
" +
name);
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
动态代理对象
*
@author partner4java
*
*/
public class LogHandler implements InvocationHandler
{
private Object
delegate;
public Object
bind(Object delegate){
this.delegate
= delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), this);
}
/**
* 代理对象,这里面还可以改变原有的方法
*/
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Object
result = null;
try {
System.out.println("添加日志");
result
= method.invoke(delegate, args);
} catch (Exception
e) {
e.printStackTrace();
}
return null;
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
/**
*
测试
*
@author partner4java
*
*/
public class ProxyDemo
{
public static void main(String[]
args) {
LogHandler
logHandler = new LogHandler();
IHello
iHello = (IHello) logHandler.bind(new HelloSpeaker());
iHello.hello("long");
}
}
3Spring中的AOP
利用ProxyFactory连接CGLIB简单实现AOP:
加入包aopalliance.jar\cglib-nodep-2.1_3.jar
demo:
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.proxyfactory;
/**
*
被代理的对象
*
@author partner4java
*
*/
public class MessageWriter
{
public void writeMessage(){
System.out.println("world!");
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.proxyfactory;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
*
装饰者<br/>
*
MethodInterceptor接口是对方法调用连接点实现包围通知的AOP联盟标准接口
*
@author partner4java
*
*/
public class MessageDecorator implements MethodInterceptor{
public Object
invoke(MethodInvocation invocation) throws Throwable
{
System.out.print("Hello
");
Object
retVal = invocation.proceed();
return retVal;
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.proxyfactory;
import org.springframework.aop.framework.ProxyFactory;
/**
*
调用组装
*
这里最重要的部分是我们使用ProxyFactory来创建一个目标对象代理,同时织入通知
*
@author partner4java
*
*/
public class HelloWorldWeaver
{
public static void main(String[]
args) {
//目标
MessageWriter
target = new MessageWriter();
//create
the proxy
ProxyFactory
proxyFactory = new ProxyFactory();
proxyFactory.addAdvice(new MessageDecorator());
proxyFactory.setTarget(target);
//获取返回被代理的目标
MessageWriter
proxy = (MessageWriter) proxyFactory.getProxy();
target.writeMessage();
System.out.println("---");
proxy.writeMessage();
// 后台打印:
// world!
// ---
// World
world!
}
}
Spring内部两种实现代理的方法:JDK动态代理和CGLIB代理。
ProxyFactory类控制着Spring AOP中的织入和创建代理的过程。
141-155各种通知(前置、后置等等)
4Spring里的通知者和切入点
155-176 讲解手工实现接口来实现切入点的方法
5代理详解
代理的核心就是拦截方法调用,并在需要的时候执行匹配某方法的通知链。
和CGLIB不同的是,JDK代理只能代理接口,不能代理类。
使用JDK代理时,如何处理一个特定的方法调用的决定是在程序运行时做出的,也就是在每次方法被调用时。使用CGLIB代理可以边开这种处理方法,CGLIB会在运行中随时为代理创建新类的字节码,并尽可能的重用已经生成的类的字节码。
AOP的核心概念:
连接点(jointpoint):一个连接点是一个程序执行过程中的特定点。
通知(advice):在某一特定的连接点处运行的代码成为“通知”。
切入点(pointcut):切入点是用来定义某一个通知该何时执行的一组连接点。
方面(aspect):通知和切入点的组合叫做方面。
织入(weaving):织入是将方面真正的加入程序代码的过程。
目标(target):如果一个对象的执行过程受到某个AOP操作的修改,那么他就叫做一个目标对象,也成为通知对象。
引入(introduction):通过引入,我们可以在一个对象中加入新的方法或者字段,以改变他的结构。
2AOP的类型
两种类型AOP:静态AOP和动态AOP。
静态代理:
代理对象与被代理对象必须实现同一个接口。
demo:
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
静态代理,统一接口
*
@author partner4java
*
*/
public interface IHello
{
/**
* 可以带来的统一方法
* @param name
*/
public void hello(String
name);
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
被代理的对象,需要借助代理对象加入日志
*
@author partner4java
*
*/
public class HelloSpeaker implements IHello
{
public void hello(String
name) {
System.out.println("Hello
" +
name);
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
代理对象,给被代理对象添加日志
*/
public class HelloProxy implements IHello
{
private IHello
iHello;
public HelloProxy(IHello
iHello) {
super();
this.iHello
= iHello;
}
public void hello(String
name) {
System.out.println("记录日志");
iHello.hello(name);
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.staticproxy;
/**
*
调用
*
@author partner4java
*
*/
public class ProxyDemo
{
public static void main(String[]
args) {
IHello
iHello = new HelloProxy(new HelloSpeaker());
iHello.hello("long");
}
}
动态代理:
动态代理区别于静态带来实现的地方在于织入过程是在运行时动态进行的。自己实现一般实现java.lang.reflect.InvocationHandler接口。
例子:
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
public interface IHello
{
public void hello(String
name);
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
/**
*
被代理的对象,需要借助代理对象加入日志
*
@author partner4java
*
*/
public class HelloSpeaker implements IHello
{
public void hello(String
name) {
System.out.println("Hello
" +
name);
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
动态代理对象
*
@author partner4java
*
*/
public class LogHandler implements InvocationHandler
{
private Object
delegate;
public Object
bind(Object delegate){
this.delegate
= delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), this);
}
/**
* 代理对象,这里面还可以改变原有的方法
*/
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Object
result = null;
try {
System.out.println("添加日志");
result
= method.invoke(delegate, args);
} catch (Exception
e) {
e.printStackTrace();
}
return null;
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.dynamicproxy;
/**
*
测试
*
@author partner4java
*
*/
public class ProxyDemo
{
public static void main(String[]
args) {
LogHandler
logHandler = new LogHandler();
IHello
iHello = (IHello) logHandler.bind(new HelloSpeaker());
iHello.hello("long");
}
}
3Spring中的AOP
利用ProxyFactory连接CGLIB简单实现AOP:
加入包aopalliance.jar\cglib-nodep-2.1_3.jar
demo:
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.proxyfactory;
/**
*
被代理的对象
*
@author partner4java
*
*/
public class MessageWriter
{
public void writeMessage(){
System.out.println("world!");
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.proxyfactory;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
*
装饰者<br/>
*
MethodInterceptor接口是对方法调用连接点实现包围通知的AOP联盟标准接口
*
@author partner4java
*
*/
public class MessageDecorator implements MethodInterceptor{
public Object
invoke(MethodInvocation invocation) throws Throwable
{
System.out.print("Hello
");
Object
retVal = invocation.proceed();
return retVal;
}
}
view
plaincopy
to clipboardprint?
package cn.partner4java.proxy.proxyfactory;
import org.springframework.aop.framework.ProxyFactory;
/**
*
调用组装
*
这里最重要的部分是我们使用ProxyFactory来创建一个目标对象代理,同时织入通知
*
@author partner4java
*
*/
public class HelloWorldWeaver
{
public static void main(String[]
args) {
//目标
MessageWriter
target = new MessageWriter();
//create
the proxy
ProxyFactory
proxyFactory = new ProxyFactory();
proxyFactory.addAdvice(new MessageDecorator());
proxyFactory.setTarget(target);
//获取返回被代理的目标
MessageWriter
proxy = (MessageWriter) proxyFactory.getProxy();
target.writeMessage();
System.out.println("---");
proxy.writeMessage();
// 后台打印:
// world!
// ---
// World
world!
}
}
Spring内部两种实现代理的方法:JDK动态代理和CGLIB代理。
ProxyFactory类控制着Spring AOP中的织入和创建代理的过程。
141-155各种通知(前置、后置等等)
4Spring里的通知者和切入点
155-176 讲解手工实现接口来实现切入点的方法
5代理详解
代理的核心就是拦截方法调用,并在需要的时候执行匹配某方法的通知链。
和CGLIB不同的是,JDK代理只能代理接口,不能代理类。
使用JDK代理时,如何处理一个特定的方法调用的决定是在程序运行时做出的,也就是在每次方法被调用时。使用CGLIB代理可以边开这种处理方法,CGLIB会在运行中随时为代理创建新类的字节码,并尽可能的重用已经生成的类的字节码。
相关文章推荐
- Spring高级程序设计 6 Spring AOP 进阶
- Spring3.0读书笔记----(六)Spring AOP基础
- JavaEE框架——Spring入门基础(控制反转Ioc和切面技术Aop)
- Spring基础-AOP基本概念和特点(四)
- Spring AOP基础 注解方式
- Spring框架 之 Spring AOP理论基础
- Spring-AOP---【基础理论篇】
- Spring高级程序设计 16 事务管理
- Spring基础之AOP
- spring的AOP调用(二)DAO层的AOP实现保存基础表数据
- Spring_16_AOP 基础
- java基础之实现类似spring的可配置的AOP
- Spring之AOP基础
- Spring基础-AOP之ProxyFactoryBean及相关内容(五)
- Spring(基础)学习文档五(spring的aop详解)
- Spring基础系列--AOP织入逻辑跟踪
- Spring基础---AOP使用拓展
- spring学习总结(九):AOP 基础及基于注解配置的AOP
- [Java]Spring AOP基础知识-动态代理
- Spring AOP 基础知识2