Spring AOP代理主要分为JDKProxy代理和Cglib代理 。
1. jdk要代理的类要有其对就的接口类,而Cblib代理的类则不需要。
2. jdk代理类生成类要实现
3.静态代理 每一个类接口都要有其对应的代理实现类
package proxy; /** * @author dk * @date 2015/10/10 * 如果用静态代理,每一个类接口都要有其对应的代理实现类 */ public class StaticProxy implements UserService { @Override public void addUser() { userService.addUser(); } @Override public void removeUser() { } @Override public void searchUser() { } public UserService userService; public StaticProxy(UserService userService) { this.userService = userService; } }
InvocationHandler(java.lang.reflect.InvocationHandler)接口,而Cglib代理类生成类要实现MethodInterceptor(net.sf.cglib.proxy.MethodInterceptor).
JDK动态代理是针对接口的,而cglib是针对类来实现代理的,cglib的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
4. 实现类代码:
jdkProxy:
this.targetObject = targetObject;
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this);
cglibProxy:
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
enhancer.setCallback(this);
return enhancer.create();
全部代码:
package com.aop.service;
public interface UserService {
public void save(String name);
}
package com.aop.service.impl;
import com.aop.service.UserService;
public class UserServiceBen implements UserService {
private String role = null;
public String getRole() {
return role;
}
public UserServiceBen(String role) {
this.role = role;
}
@Override
public void save(String name) {
System.out.println("正在保存用户的姓名:"+name);
}
}
package com.aop.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.aop.service.impl.UserServiceBen;
public class JDKProxy implements InvocationHandler {
public Object targetObject;
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {//环绕通知
Object result = null;
UserServiceBen bean = (UserServiceBen)targetObject;
if(bean.getRole() != null){
// ... before advice--> 前置通知
try {
result = method.invoke(targetObject, args);
////after advice--> 后置通知
} catch (Exception e) {
//exception advice--> 例外通知
e.printStackTrace();
}finally{
//finalAdvice--> 最终通知
}
}
return result;
}
}
package com.aop.service.impl;
public class UserServiceCGLIBBen{
private String role = null;
public String getRole() {
return role;
}
public UserServiceCGLIBBen() {
super();//cglib proxy 这个必须存在
// TODO Auto-generated constructor stub
}
public UserServiceCGLIBBen(String role) {
super();
this.role = role;
}
public void save(String name) {
System.out.println("正在保存用户的姓名:"+name);
}
}
package com.aop.proxy;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.aop.service.impl.UserServiceBen;
import com.aop.service.impl.UserServiceCGLIBBen;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGLIBProxy implements MethodInterceptor {
public Object targetObject;
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object result = null;
UserServiceCGLIBBen bean = (UserServiceCGLIBBen)targetObject;
if(bean.getRole() != null){
result = method.invoke(targetObject, args);
}
return result;
}
}
测试类
package com.aop.test;
import static org.junit.Assert.*;
import org.junit.Test;
import com.aop.proxy.CGLIBProxy;
import com.aop.proxy.JDKProxy;
import com.aop.service.UserService;
import com.aop.service.impl.UserServiceBen;
import com.aop.service.impl.UserServiceCGLIBBen;
public class ProxyTest {
@Test
public void test() {
fail("Not yet implemented");
}
@Test
public void JDKProxyTest1(){
JDKProxy proxy = new JDKProxy();
UserService service =(UserService)proxy.createProxyInstance(new UserServiceBen("admin"));
service.save("baby");
}
@Test
public void JDKProxyTest2(){
JDKProxy proxy = new JDKProxy();
UserService service =(UserService)proxy.createProxyInstance(new UserServiceBen(null));
service.save("baby");
}
@Test
public void CGLIBProxyTest1(){
CGLIBProxy proxy = new CGLIBProxy();
UserServiceCGLIBBen service =(UserServiceCGLIBBen)proxy.createProxyInstance(new UserServiceCGLIBBen("gogo"));
service.save("baby");
}
@Test
public void CGLIBProxyTest2(){
CGLIBProxy proxy = new CGLIBProxy();
UserServiceCGLIBBen service =(UserServiceCGLIBBen)proxy.createProxyInstance(new UserServiceCGLIBBen(null));
service.save("baby");
}
}
观察代码可以发现每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成。
再来看一下动态代理:
JDK动态代理中包含一个类和一个接口:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
参数说明:
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
参数说明:
ClassLoader loader:类加载器
Class<?>[] interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
Ps:类加载器
在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器;
Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的;
Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类;
AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。
动态代理
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
Cglib动态代理中包含一个类和一个接口:
MethodInterceptor接口:
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object result = null;
UserServiceCGLIBBen bean = (UserServiceCGLIBBen)targetObject;
if(bean.getRole() != null){
result = method.invoke(targetObject, args);
}
return result;
}
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
MethodProxy:方法代理
Aspect(切面):横切性关注点的抽象。
Joinpoint(连接点):那些被拦截到的点。在Spring中,这些点指的是方法。
Pointcut(切入点):要对那些joipoint进行拦截的定义。
Advice(通知):拦截到joinpoint之后的所要做的事情(记日志等)
Target(目标):代理的目标对象。
Introdution(引入):在不修改代码的前提下,Introdution可以在运行期为类动态加载地添加一些方法和Field
Weave(织入):指将Aspect运用到target对象并导致proxy对象创建的过程。
相关推荐
3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...
spring aop jar 包
描述一下Spring AOP? 在Spring AOP中关注点(concern)和横切关注点(cross-cutting concern)有什么不同? AOP有哪些可用的实现? Spring中有哪些不同的通知类型(advice types)? Spring AOP 代理是什么? 引介...
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序
spring aop切面拦截指定类和方法实现流程日志跟踪 一般情况下,在不侵入业务代码的情况下,需要做流程日志跟踪是比较合理的 采用springaop切面思想
AOP的意思就是面向切面编程。本文主要是通过梳理JDK中自带的反射机制,实现 AOP动态代理模式,这也是Spring AOP 的实现原理
springaop依赖的jar包,spring版本2.5.6,如果需要,可以下载使用,欢迎各位评论指出不足
springAOP配置实现动态代理,有利于熟悉动态代理原理,深入了解spring。
Spring源码最难问题:当Spring AOP遇上循环依赖.docx
spring aop的demo spring aop的demo
Spring AOP 入门 作者:廖雪峰
spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop
Spring AOP 日志管理 实例LoggingThrowsAdvice.java
Spring AOP 几个不同使用方法的完整例子,使用Junit4c测试, 在我的博客上有不同配置组合的说明,可以参考
Spring AOP的实现机制中文版,动态代理及原理,自定义类加载器
Spring AOP简单demo 入门级的 advice
springAOP详解
spring aop 经典例子(原创),无论新手还是老手,可以快速对Spring AOP有个总体的认识。基于JDK1.6,Spring2.0.5,Eclipse IDE。
springaop多数据库读写分离