Skip to content

Commit

Permalink
fix:修改整体动态代理代码
Browse files Browse the repository at this point in the history
  • Loading branch information
maxy19 committed Dec 15, 2019
1 parent ac95e86 commit 58f9bf2
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 57 deletions.
3 changes: 1 addition & 2 deletions src/main/com/mxy/design/proxy/SchoolImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
public class SchoolImpl implements ISchool {

public SchoolImpl(){
//JDK动态代理通过反射会调用这个方法
System.out.println(SchoolImpl.class+":JDK 动态代理反射调用。");
}

@Override
public void save() {
System.out.println("保存学校信息ing");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
/**
* 动态代理 实现GGLIB 接口
* 注意:
* CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,
* CGLIB是针对类实现代理,主要是对指定的类生成一个子类,
* 并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,
* 对于final类或方法,是无法继承的。
*/
public class StudentCglibProxy implements MethodInterceptor {
public class CglibProxy implements MethodInterceptor {
/**
* CGLib需要代理的目标对象
*/
Expand All @@ -24,7 +24,10 @@ public Object intercept(Object obj, Method method, Object[] args, MethodProxy me
//可能造成死循环坑:而如果调用invokeSuper方法,则一定要使用被代理后的obj对象
//return methodProxy.invokeSuper(obj, args);
//可能造成死循环坑:如果是用invoke方法一定要使用被代理的对象也就是上文中的target
return methodProxy.invoke(target, args);
System.out.println("被代理对象:" + target.getClass() + ":调用方法:" + method.getName() + ":前置通知:开启事务");
Object invoke = methodProxy.invoke(target, args);
System.out.println("被代理对象:" + target.getClass() + ":调用方法:" + method.getName() + ":后置通知:提交事务");
return invoke;
}

public <T> T getInstance(Object target) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ public class StudentService {

public StudentService() {
//CGLIB动态代理通过反射会调用这个方法
System.out.println("基类==> CGLIB 动态代理反射调用。");
System.out.println("studentService===>基类类构造方法");
}

public StudentService(String str) {
//避免混淆
//避免与当通过代理初始化对象空构造时候打印内容混淆
}

public void save() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
public class StudentServiceExtend extends StudentService {

public StudentServiceExtend() {
System.out.println("===>扩展类构造方法");
System.out.println("studentServiceExtend===>扩展类构造方法");
}

public StudentServiceExtend(String str) {
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
public class StudentServiceExtendChildren extends StudentServiceExtend {

public StudentServiceExtendChildren() {
System.out.println("===>扩展类子类构造方法");
System.out.println("studentServiceExtendChildren===>扩展类子类构造方法");
}

public StudentServiceExtendChildren(String str) {
//避免与当通过代理初始化对象空构造时候打印内容混淆
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.mxy.design.proxy.dynamic.cglib.proxy;

public class TeacherService {

public TeacherService() {
System.out.println("teacherService===>基类类构造方法");
}
public TeacherService(String str) {
//避免与当通过代理初始化对象空构造时候打印内容混淆
}

public void save() {
System.out.println("保存ing");
}

public void delete() {
System.out.println("删除ing");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
* 1.当Bean实现接口时,Spring就会用JDK的动态代理。
* 2.当Bean没有实现接口时,Spring使用CGlib是实现。
*/
public class SchoolJdkProxy implements InvocationHandler {
public class JdkProxy implements InvocationHandler {

private Object target;

public SchoolJdkProxy(Object object) {
this.target = object;
}

public <T> T getInstance() {
public <T> T getInstance(Object target) {
this.target = target;
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
System.out.println("被代理对象:" + target.getClass() + ":调用方法:" + method.getName() + ":前置通知:开启事务");
Object invoke = method.invoke(target, args);
System.out.println("被代理对象:" + target.getClass() + ":调用方法:" + method.getName() + ":后置通知:提交事务");
return invoke;
}
}
25 changes: 25 additions & 0 deletions src/main/com/mxy/design/proxy/dynamic/jdk/proxy/SchoolImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.mxy.design.proxy.dynamic.jdk.proxy;

import com.mxy.design.proxy.ISchool;

public class SchoolImpl implements ISchool {

public SchoolImpl(){
//JDK动态代理通过反射会调用这个方法
System.out.println(SchoolImpl.class+":JDK 动态代理反射调用。");
}

public SchoolImpl(String str) {
//避免与当通过代理初始化对象空构造时候打印内容混淆
}

@Override
public void save() {
System.out.println("保存学校信息ing");
}

@Override
public void delete() {
System.out.println("删除学校信息ing");
}
}
57 changes: 16 additions & 41 deletions src/test/com/mxy/design/proxy/DynamicProxyTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.mxy.design.proxy;

import com.mxy.design.proxy.dynamic.cglib.proxy.StudentCglibProxy;
import com.mxy.design.proxy.dynamic.cglib.proxy.CglibProxy;
import com.mxy.design.proxy.dynamic.cglib.proxy.StudentService;
import com.mxy.design.proxy.dynamic.cglib.proxy.StudentServiceExtendChildren;
import com.mxy.design.proxy.dynamic.jdk.proxy.SchoolJdkProxy;
import com.mxy.design.proxy.dynamic.cglib.proxy.TeacherService;
import com.mxy.design.proxy.dynamic.jdk.proxy.JdkProxy;
import com.mxy.design.proxy.dynamic.jdk.proxy.SchoolImpl;
import org.junit.Test;

import java.util.Random;
import java.io.IOException;

/**
* 装饰模式:增加功能,不改变接口
Expand All @@ -21,55 +23,28 @@
public class DynamicProxyTest {

@Test
public void cglibProxyTest() {
public void cglibProxyTest() throws IOException {
System.out.println("=====使用CGLIB代理模式");
//去掉下面注释可以 会在指定位置生成文件
//System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, ".\\\\classes");
StudentService cglibProxy = new StudentCglibProxy().getInstance(new StudentServiceExtendChildren());
save(cglibProxy);
delete(cglibProxy);
TeacherService teacherService = new CglibProxy().getInstance(new TeacherService(""));
teacherService.save();

System.out.println();

StudentService studentService = new CglibProxy().getInstance(new StudentServiceExtendChildren(""));
studentService.delete();
}

@Test
public void jdkProxyTest() {
System.out.println("=====使用JDK动态代理模式");
ISchool jdkProxy = new SchoolJdkProxy(new SchoolImpl()).getInstance();
//与静态代理输出结果保持一致
save(jdkProxy);
//查询是否存在
delete(jdkProxy);
}

private void delete(ISchool jdkProxy) {
if (new Random().nextBoolean()) {
System.out.println("===开启事务");
jdkProxy.delete();
System.out.println("===提交事务");
} else {
System.out.println("===该用户已经被删除");
}
}
ISchool jdkProxy = new JdkProxy().getInstance(new SchoolImpl(""));

private void save(ISchool jdkProxy) {
System.out.println("==开启事务");
jdkProxy.save();
System.out.println("==提交事务");
}

public void save(StudentService cglibProxy) {
System.out.println("==开启事务");
cglibProxy.save();
System.out.println("==提交事务");
}
System.out.println();

public void delete(StudentService cglibProxy) {
if (new Random().nextBoolean()) {
System.out.println("===开启事务");
cglibProxy.delete();
System.out.println("===提交事务");
} else {
System.out.println("===该用户已经被删除");
}
jdkProxy.delete();
}

}

0 comments on commit 58f9bf2

Please sign in to comment.