`
perfect5085
  • 浏览: 269682 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java中AOP技术详解

 
阅读更多

 

AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,与OOP(Object Oriented Programming)面向对象编程对等,都是一种编程思想。
从OOP角度分析,我们关注业务的处理逻辑,是属于纵向的行为,从AOP角度分析,我们关注对象行为发生时的问题,是属于横向的行为。

AOP 作用:
1	监控函数的调用
2	捕获异常发生

实际应用在:事务、安全、日志等横切关注。

两种实现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....................


切面(Aspect):对横切关注点的抽象(类似类对对象的抽象) 
连接点(JoinPoint):被拦截到的点,泛指方法 
切入点(CutPoint):对哪些连接点进行拦截的定义 
通知(Advice):在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知(调用方法之前执行,全部执行完毕之后) 
引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。 
目标对象(Target Object): 包含连接点的对象。也被称作 被通知或被代理对象。 
AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 
织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时 完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样, 在运行时完成织入。 
分享到:
评论
2 楼 weizhikang1992 2016-06-22  
[b]
[flash=200,200][list]
[*]
引用
[/list]          [/flash]
[/b]
1 楼 lizhengzy 2015-07-04  

    [啊啊啊]

相关推荐

Global site tag (gtag.js) - Google Analytics