1、Spring核心-AOP-动态代理-基于JDK代理1
1、动态代理:
静态代理:要求代理类一定存在,
动态代理:程序运行的时候,根据要被代理的对象动态生成代理类。
类型:
1
、基于
JDK
的动态代理
2
、基于
CGLIB
的动态代理
2、举个例子来感受一下 jdk 动态代理
需要用到的一些类
import com.zj.aop.AOP;
public class LogAopImpl implements AOP {
/**
* 切面:服务代码,切到核心代码当中去。切入到那里,我们举例子,给了四个位置;
*/
@Override
public void before() {
System.out.println("日志---------before----------");
}
@Override
public void after() {
System.out.println("日志---------after----------");
}
@Override
public void exception() {
System.out.println("日志---------exception----------");
}
@Override
public void myFinally() {
System.out.println("日志---------myFinally----------");
}
}
import com.zj.aop.AOP;
public class TranAop implements AOP {
/**
* 切面:服务代码,切到核心代码当中去。切入到那里,我们举例子,给了四个位置;
*/
@Override
public void before() {
System.out.println("事务----------before--------");
}
@Override
public void after() {
System.out.println("事务----------after--------");
}
@Override
public void exception() {
System.out.println("事务----------exception--------");
}
@Override
public void myFinally() {
System.out.println("事务----------myFinally--------");
}
}
创建一个包,包里面创建一个类MyJdkProxy
import com.zj.service.TeamService;
import com.zj.service.impl.TeamServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyJdkProxy {
public static void main(String[] args) {
//目标对象---------被代理对象
TeamService teamService = new TeamServiceImpl();
//返回代理对象,基于jdk的动态代理
TeamService proxyService = (TeamService) Proxy.newProxyInstance(teamService.getClass().getClassLoader(), teamService.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
System.out.println("事务开始");
Object invoke = method.invoke(teamService, args);//核心方法
System.out.println("事务结束");
return invoke;
}catch (Exception e){
System.out.println("事务回滚");
e.printStackTrace();
throw e;
}finally {
System.out.println("finally----------");
}
}
});
//让代理对象干活
proxyService.add();
//获取各自的类型
System.out.println(teamService.getClass());
System.out.println(proxyService.getClass());
}
}
结果:
事务开始
TeamService-----add-----
事务结束
finally----------
class com.zj.service.impl.TeamServiceImpl
class com.sun.proxy.$Proxy0
让我们来对上面的代码进行一个优化
创建一个proxyHandler对象
import com.zj.aop.AOP;
import com.zj.service.TeamService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyHandler implements InvocationHandler {
//被代理的对象,采用的是接口的形式
private TeamService teamService;
//切面对象
private AOP aop;
//定义一个全参构造方法,让我们在创建对象的时候定义好他们。
public ProxyHandler(TeamService teamService, AOP aop) {
this.teamService = teamService;
this.aop = aop;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
aop.before();
Object invoke = method.invoke(teamService, args);//核心方法
aop.after();
return invoke;
}catch (Exception e){
aop.exception();
e.printStackTrace();
throw e;
}finally {
aop.myFinally();
}
}
}
import com.zj.aop.AOP;
import com.zj.aop.impl.LogAopImpl;
import com.zj.service.TeamService;
import com.zj.service.impl.TeamServiceImpl;
import java.lang.reflect.Proxy;
public class MyJdkProxy {
public static void main(String[] args) {
//目标对象---------被代理对象
TeamService teamService = new TeamServiceImpl();
//创建切面对象
AOP logAop = new LogAopImpl();
//返回代理对象,基于jdk的动态代理
TeamService service = (TeamService) Proxy.newProxyInstance(teamService.getClass().getClassLoader(), teamService.getClass().getInterfaces(),
new ProxyHandler(teamService, logAop));
//让代理对象干活
service.add();
}
}
再次优化
创建一个产生代理对象的工产:
import com.zj.aop.AOP;
import com.zj.service.TeamService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
//被代理类
private TeamService teamService;
private AOP aop;
public ProxyFactory(TeamService teamService, AOP aop) {
this.teamService = teamService;
this.aop = aop;
}
public Object getProxyInstance(){
return Proxy.newProxyInstance(
teamService.getClass().getClassLoader(),
teamService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
aop.before();
Object invoke = method.invoke(teamService, args);
aop.after();
return invoke;
}catch (Exception e) {
e.printStackTrace();
return e;
} finally {
aop.myFinally();
}
}
}
);
}
}
测试类:
import com.zj.aop.AOP;
import com.zj.aop.impl.LogAopImpl;
import com.zj.aop.impl.TranAop;
import com.zj.service.TeamService;
import com.zj.service.impl.TeamServiceImpl;
public class MyJdkProxy {
public static void main(String[] args) {
//目标对象---------被代理对象
TeamService teamService = new TeamServiceImpl();
//创建切面对象
AOP logAop = new LogAopImpl();
AOP tranAop = new TranAop();
//返回代理对象,基于jdk的动态代理
TeamService service = (TeamService) new ProxyFactory(teamService, logAop).getProxyInstance();
TeamService service1 = (TeamService) new ProxyFactory(service, tranAop).getProxyInstance();
//让代理对象干活
service1.add();
}
}
4、jdk动态代理的总结:
代理对象不需要实现接口,但是目标对象一定要实现接口;否则不能用
JDK
动态代理
3、Spring核心-AOP-动态代理-基于CGLIB代理1
1、如果想要功能扩展,但目标对象没有实现接口,怎样功能扩展。我们可以根据子类的方式实
现动态代理CGLIB。
2、Cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。
JDK
的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没 有 实现接口的类,就可以使用CGLIB
实现。 CGLIB是一个强大的高性能的代码生成包,它可以 在运行期扩展
Java
类与实现
Java
接口。它广泛的 被许多AOP
的框架使用,例如
Spring AOP
和
dynaop
,为他们提供方法的
interception
。 CGLIB包的底层是通过使用一个小而快的字 节码处理框架
ASM
,来转换字节码并生成新的类。不鼓 励直接使用ASM
,因为它要求你必须 对
JVM
内部结构包括
class
文件的格式和指令集都很熟悉。
3、通过一个小小的案例来说明一下使用方法:
1)在pom.xml中导入cglib的依赖包
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.2</version>
</dependency>
2)创建一个包cglibProxy,在包中创建一个类,MyCglibProxy,在创建一个类,不实现任何接口
NBAService类
package com.zj.cglibProxy;
public class NBAService {
public int add(int a,int b){
return a+b;
}
}
MyCglibProxy类
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyCglibProxy {
public static void main(String[] args) {
//被代理类
NBAService nbaService = new NBAService();
//创建代理对象,选择cglib动态代理
//这里的代理和被代理的类的类型相同
NBAService service = (NBAService) Enhancer.create(nbaService.getClass(),
new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
try {
System.out.println("开始事务");
methodProxy.invokeSuper(o, objects);//核心
System.out.println("结束事务");
return null;
} catch (Exception e) {
System.out.println("事务回滚");
return e;
} finally {
System.out.println("finally------------");
}
}
});
//带代理对象执行任务
int sum = service.add(1, 2);
System.out.println(sum);
}
}
将main方法中的cglibProxy运用结构化一下
在同一个包下创建一个cglibProxyFactory类:
import com.zj.aop.AOP;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyFactory {
//定义一个被代理的对象
private NBAService nbaService;
//定义切面
private AOP aop;
//写一个方法,返回的是代理对象
public Object getProxyInstance(NBAService nbaService, AOP aop){
return Enhancer.create(nbaService.getClass(),
new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
try {
aop.before();
Object o1 = methodProxy.invokeSuper(o, objects);
aop.after();
return null;
} catch (Exception e) {
aop.exception();
return e;
} finally {
aop.myFinally();
}
}
});
}
}
测试类
public static void main(String[] args) {
//被代理类
NBAService nbaService = new NBAService();
//创建切面
AOP tranAop = new TranAop();
AOP logAop = new LogAopImpl();
//创建工厂类
NBAService service =(NBAService) new CglibProxyFactory().getProxyInstance(nbaService,tranAop);
NBAService service1 =(NBAService) new CglibProxyFactory().getProxyInstance(service,logAop);
//让代理类去干活
int sum = service1.add(1, 2);
System.out.println(sum);
}