From b69409a9e456acf054f975202092b255c1a379cc Mon Sep 17 00:00:00 2001
From: maxy19 <315802767@qq.com>
Date: Sat, 14 Dec 2019 12:47:19 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=E5=A2=9E=E5=8A=A0cglib=20=E5=9F=BA?=
=?UTF-8?q?=E7=B1=BB=E6=B5=8B=E8=AF=95=E5=85=B6=E7=BB=93=E6=9E=9C=E3=80=82?=
=?UTF-8?q?=E8=AF=81=E6=98=8E=E4=BB=A3=E7=90=86=E7=B1=BB=E7=94=9F=E6=88=90?=
=?UTF-8?q?=E8=BF=87=E7=A8=8B=E4=BB=A5=E6=89=A7=E8=A1=8C=E8=BF=87=E7=A8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 105 ++++++++++++++++++
pom.xml | 2 +-
.../proxy/{IStudent.java => ISchool.java} | 2 +-
src/main/com/mxy/design/proxy/SchoolImpl.java | 18 +++
.../com/mxy/design/proxy/SchoolProxy.java | 28 +++++
.../com/mxy/design/proxy/StudentImpl.java | 13 ---
.../com/mxy/design/proxy/StudentProxy.java | 36 ------
.../proxy/dynamic/cglib/proxy/IStudent.java | 9 --
.../cglib/proxy/StudentCglibProxy.java | 23 +++-
.../dynamic/cglib/proxy/StudentImpl.java | 13 ---
.../dynamic/cglib/proxy/StudentService.java | 20 ++++
.../cglib/proxy/StudentServiceExtend.java | 20 ++++
.../proxy/StudentServiceExtendChildren.java | 18 +++
.../proxy/dynamic/jdk/proxy/IStudent.java | 9 --
...udentJdkProxy.java => SchoolJdkProxy.java} | 8 +-
.../proxy/dynamic/jdk/proxy/StudentImpl.java | 13 ---
.../mxy/design/proxy/DynamicProxyTest.java | 49 ++++----
.../com/mxy/design/proxy/StaticProxyTest.java | 10 +-
18 files changed, 267 insertions(+), 129 deletions(-)
create mode 100644 .gitignore
rename src/main/com/mxy/design/proxy/{IStudent.java => ISchool.java} (72%)
create mode 100644 src/main/com/mxy/design/proxy/SchoolImpl.java
create mode 100644 src/main/com/mxy/design/proxy/SchoolProxy.java
delete mode 100644 src/main/com/mxy/design/proxy/StudentImpl.java
delete mode 100644 src/main/com/mxy/design/proxy/StudentProxy.java
delete mode 100644 src/main/com/mxy/design/proxy/dynamic/cglib/proxy/IStudent.java
delete mode 100644 src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentImpl.java
create mode 100644 src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentService.java
create mode 100644 src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtend.java
create mode 100644 src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtendChildren.java
delete mode 100644 src/main/com/mxy/design/proxy/dynamic/jdk/proxy/IStudent.java
rename src/main/com/mxy/design/proxy/dynamic/jdk/proxy/{StudentJdkProxy.java => SchoolJdkProxy.java} (58%)
delete mode 100644 src/main/com/mxy/design/proxy/dynamic/jdk/proxy/StudentImpl.java
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2e9e66e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,105 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+*.iml
+out
+gen
+target
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Java template
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
diff --git a/pom.xml b/pom.xml
index 4a97004..504974e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,7 +88,7 @@
cglib
cglib
- 3.2.10
+ 3.3.0
diff --git a/src/main/com/mxy/design/proxy/IStudent.java b/src/main/com/mxy/design/proxy/ISchool.java
similarity index 72%
rename from src/main/com/mxy/design/proxy/IStudent.java
rename to src/main/com/mxy/design/proxy/ISchool.java
index 2477d73..93abe3f 100644
--- a/src/main/com/mxy/design/proxy/IStudent.java
+++ b/src/main/com/mxy/design/proxy/ISchool.java
@@ -1,6 +1,6 @@
package com.mxy.design.proxy;
-public interface IStudent {
+public interface ISchool {
void save();
diff --git a/src/main/com/mxy/design/proxy/SchoolImpl.java b/src/main/com/mxy/design/proxy/SchoolImpl.java
new file mode 100644
index 0000000..721c538
--- /dev/null
+++ b/src/main/com/mxy/design/proxy/SchoolImpl.java
@@ -0,0 +1,18 @@
+package com.mxy.design.proxy;
+
+public class SchoolImpl implements ISchool {
+
+ public SchoolImpl(){
+ //JDK动态代理通过反射会调用这个方法
+ System.out.println(SchoolImpl.class+":JDK 动态代理反射调用。");
+ }
+ @Override
+ public void save() {
+ System.out.println("保存学校信息ing");
+ }
+
+ @Override
+ public void delete() {
+ System.out.println("删除学校信息ing");
+ }
+}
diff --git a/src/main/com/mxy/design/proxy/SchoolProxy.java b/src/main/com/mxy/design/proxy/SchoolProxy.java
new file mode 100644
index 0000000..b5b1d21
--- /dev/null
+++ b/src/main/com/mxy/design/proxy/SchoolProxy.java
@@ -0,0 +1,28 @@
+package com.mxy.design.proxy;
+
+/**
+ * 重点类 静态代理 实现目标接口
+ */
+public class SchoolProxy implements ISchool {
+
+ private ISchool student;
+
+ public SchoolProxy(ISchool iSchool) {
+ this.student = iSchool;
+ }
+
+ @Override
+ public void save() {
+ System.out.println("==开启事务");
+ student.save();
+ System.out.println("==提交事务");
+ }
+
+ @Override
+ public void delete() {
+ //查询是否存在
+ System.out.println("===开启事务");
+ student.delete();
+ System.out.println("===提交事务");
+ }
+}
diff --git a/src/main/com/mxy/design/proxy/StudentImpl.java b/src/main/com/mxy/design/proxy/StudentImpl.java
deleted file mode 100644
index 3193002..0000000
--- a/src/main/com/mxy/design/proxy/StudentImpl.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.mxy.design.proxy;
-
-public class StudentImpl implements IStudent {
- @Override
- public void save() {
- System.out.println("保存ing");
- }
-
- @Override
- public void delete() {
- System.out.println("删除ing");
- }
-}
diff --git a/src/main/com/mxy/design/proxy/StudentProxy.java b/src/main/com/mxy/design/proxy/StudentProxy.java
deleted file mode 100644
index f5271c0..0000000
--- a/src/main/com/mxy/design/proxy/StudentProxy.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.mxy.design.proxy;
-
-import java.util.Random;
-
-/**
- * 重点类 静态代理 实现目标接口
- */
-public class StudentProxy implements IStudent {
-
- private IStudent student;
-
- public StudentProxy(IStudent iStudent) {
- this.student = iStudent;
- }
-
- @Override
- public void save() {
- System.out.println("==开启事务");
- student.save();
- System.out.println("==提交事务");
- }
-
- @Override
- public void delete() {
- Random random = new Random();
- //查询是否存在
- if(random.nextBoolean()){
- System.out.println("===开启事务");
- student.delete();
- System.out.println("===提交事务");
- }else{
- System.out.println("===该用户已经被删除");
- }
-
- }
-}
diff --git a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/IStudent.java b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/IStudent.java
deleted file mode 100644
index 6ff4a41..0000000
--- a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/IStudent.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.mxy.design.proxy.dynamic.cglib.proxy;
-
-public interface IStudent {
-
- void save();
-
- void delete();
-
-}
diff --git a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentCglibProxy.java b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentCglibProxy.java
index 77f85b6..51da3d0 100644
--- a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentCglibProxy.java
+++ b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentCglibProxy.java
@@ -7,17 +7,28 @@
import java.lang.reflect.Method;
/**
- * 动态代理 实现JDK 接口
+ * 动态代理 实现GGLIB 接口
+ * 注意:
+ * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,
+ * 并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,
+ * 对于final类或方法,是无法继承的。
*/
public class StudentCglibProxy implements MethodInterceptor {
-
+ /**
+ * CGLib需要代理的目标对象
+ */
+ private Object target;
@Override
- public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
- return methodProxy.invokeSuper(o, objects);
+ public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
+ //可能造成死循环坑:而如果调用invokeSuper方法,则一定要使用被代理后的obj对象
+ //return methodProxy.invokeSuper(obj, args);
+ //可能造成死循环坑:如果是用invoke方法一定要使用被代理的对象也就是上文中的target
+ return methodProxy.invoke(target, args);
}
- public T getInstance(Class objClass) {
- return (T)Enhancer.create(objClass.getClass(), this);
+ public T getInstance(Object target) {
+ this.target = target;
+ return (T) Enhancer.create(target.getClass(), this);
}
}
diff --git a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentImpl.java b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentImpl.java
deleted file mode 100644
index dff60d9..0000000
--- a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentImpl.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.mxy.design.proxy.dynamic.cglib.proxy;
-
-public class StudentImpl implements IStudent {
- @Override
- public void save() {
- System.out.println("保存ing");
- }
-
- @Override
- public void delete() {
- System.out.println("删除ing");
- }
-}
diff --git a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentService.java b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentService.java
new file mode 100644
index 0000000..2af2074
--- /dev/null
+++ b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentService.java
@@ -0,0 +1,20 @@
+package com.mxy.design.proxy.dynamic.cglib.proxy;
+
+public class StudentService {
+
+ public StudentService() {
+ //CGLIB动态代理通过反射会调用这个方法
+ System.out.println("基类==> CGLIB 动态代理反射调用。");
+ }
+ public StudentService(String str) {
+ //避免混淆
+ }
+
+ public void save() {
+ System.out.println("保存ing");
+ }
+
+ public void delete() {
+ System.out.println("删除ing");
+ }
+}
diff --git a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtend.java b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtend.java
new file mode 100644
index 0000000..b4ea74c
--- /dev/null
+++ b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtend.java
@@ -0,0 +1,20 @@
+package com.mxy.design.proxy.dynamic.cglib.proxy;
+
+public class StudentServiceExtend extends StudentService {
+
+ public StudentServiceExtend() {
+ System.out.println("===>扩展类构造方法");
+ }
+
+ @Override
+ public void save(){
+ System.out.println("===>扩展类Save");
+ super.save();
+ }
+
+ @Override
+ public void delete(){
+ System.out.println("===>扩展类delete");
+ super.delete();
+ }
+}
diff --git a/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtendChildren.java b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtendChildren.java
new file mode 100644
index 0000000..36c86b8
--- /dev/null
+++ b/src/main/com/mxy/design/proxy/dynamic/cglib/proxy/StudentServiceExtendChildren.java
@@ -0,0 +1,18 @@
+package com.mxy.design.proxy.dynamic.cglib.proxy;
+
+public class StudentServiceExtendChildren extends StudentServiceExtend {
+
+ public StudentServiceExtendChildren() {
+ System.out.println("===>扩展类子类构造方法");
+ }
+
+ @Override
+ public void save(){
+ System.out.println("===>扩展类子类save");
+ }
+
+ @Override
+ public void delete(){
+ System.out.println("===>扩展类子类delete");
+ }
+}
diff --git a/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/IStudent.java b/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/IStudent.java
deleted file mode 100644
index 02a7667..0000000
--- a/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/IStudent.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.mxy.design.proxy.dynamic.jdk.proxy;
-
-public interface IStudent {
-
- void save();
-
- void delete();
-
-}
diff --git a/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/StudentJdkProxy.java b/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/SchoolJdkProxy.java
similarity index 58%
rename from src/main/com/mxy/design/proxy/dynamic/jdk/proxy/StudentJdkProxy.java
rename to src/main/com/mxy/design/proxy/dynamic/jdk/proxy/SchoolJdkProxy.java
index f2d6e96..183b0f5 100644
--- a/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/StudentJdkProxy.java
+++ b/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/SchoolJdkProxy.java
@@ -6,12 +6,16 @@
/**
* 动态代理 实现JDK 接口
+ * 重点:JDK动态代理只能对实现了接口的类生成代理,而不能针对类。 如果使用单纯的类,而这个类没有实现接口,会报错
+ * 在spring里面
+ * 1.当Bean实现接口时,Spring就会用JDK的动态代理。
+ * 2.当Bean没有实现接口时,Spring使用CGlib是实现。
*/
-public class StudentJdkProxy implements InvocationHandler {
+public class SchoolJdkProxy implements InvocationHandler {
private Object target;
- public StudentJdkProxy(Object object) {
+ public SchoolJdkProxy(Object object) {
this.target = object;
}
diff --git a/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/StudentImpl.java b/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/StudentImpl.java
deleted file mode 100644
index 2c7cf4e..0000000
--- a/src/main/com/mxy/design/proxy/dynamic/jdk/proxy/StudentImpl.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.mxy.design.proxy.dynamic.jdk.proxy;
-
-public class StudentImpl implements IStudent {
- @Override
- public void save() {
- System.out.println("保存ing");
- }
-
- @Override
- public void delete() {
- System.out.println("删除ing");
- }
-}
diff --git a/src/test/com/mxy/design/proxy/DynamicProxyTest.java b/src/test/com/mxy/design/proxy/DynamicProxyTest.java
index 5867323..1347c6b 100644
--- a/src/test/com/mxy/design/proxy/DynamicProxyTest.java
+++ b/src/test/com/mxy/design/proxy/DynamicProxyTest.java
@@ -1,7 +1,9 @@
package com.mxy.design.proxy;
import com.mxy.design.proxy.dynamic.cglib.proxy.StudentCglibProxy;
-import com.mxy.design.proxy.dynamic.jdk.proxy.StudentJdkProxy;
+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 org.junit.Test;
import java.util.Random;
@@ -14,42 +16,31 @@
* 代理模式:代理类对被代理的对象有控制权,决定其执行或者不执行。
* 而装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能。
* 动态代理:原理通过反射来获得代理的实现 常用的有JDK 自带jdkProxy 与 cglib 之前hibernate使用 javassist
- * 好处:当时用动态代理 一个动态代理模板就能代理多个目标类 只需要传入接口 通过反射得到实现目标类方法
+ * 好处:当使用动态代理 一个动态代理模板就能代理多个目标类 只需要传入接口 通过反射得到实现目标类方法
*/
public class DynamicProxyTest {
-
@Test
public void cglibProxyTest() {
- System.out.println("====使用代理模式前");
- IStudent iStudent = new StudentImpl();
- iStudent.save();
- iStudent.delete();
- System.out.println();
- System.out.println("=====使用CGLIB代理模式后");
- IStudent cglibProxy = new StudentCglibProxy().getInstance(IStudent.class);
+ System.out.println("=====使用CGLIB代理模式");
+ //去掉下面注释可以 会在指定位置生成文件
+ //System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, ".\\\\classes");
+ StudentService cglibProxy = new StudentCglibProxy().getInstance(new StudentServiceExtendChildren());
save(cglibProxy);
delete(cglibProxy);
}
@Test
public void jdkProxyTest() {
- System.out.println("====使用代理模式前");
- IStudent iStudent = new StudentImpl();
- iStudent.save();
- iStudent.delete();
- System.out.println();
- System.out.println("=====使用JDK动态代理模式后");
- IStudent jdkProxy = new StudentJdkProxy(iStudent).getInstance();
-
+ System.out.println("=====使用JDK动态代理模式");
+ ISchool jdkProxy = new SchoolJdkProxy(new SchoolImpl()).getInstance();
//与静态代理输出结果保持一致
save(jdkProxy);
-
//查询是否存在
delete(jdkProxy);
}
- private void delete(IStudent jdkProxy) {
+ private void delete(ISchool jdkProxy) {
if (new Random().nextBoolean()) {
System.out.println("===开启事务");
jdkProxy.delete();
@@ -59,10 +50,26 @@ private void delete(IStudent jdkProxy) {
}
}
- private void save(IStudent jdkProxy) {
+ 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("==提交事务");
+ }
+
+ public void delete(StudentService cglibProxy) {
+ if (new Random().nextBoolean()) {
+ System.out.println("===开启事务");
+ cglibProxy.delete();
+ System.out.println("===提交事务");
+ } else {
+ System.out.println("===该用户已经被删除");
+ }
+ }
+
}
diff --git a/src/test/com/mxy/design/proxy/StaticProxyTest.java b/src/test/com/mxy/design/proxy/StaticProxyTest.java
index 2d4fd1a..0816c19 100644
--- a/src/test/com/mxy/design/proxy/StaticProxyTest.java
+++ b/src/test/com/mxy/design/proxy/StaticProxyTest.java
@@ -22,12 +22,12 @@ public class StaticProxyTest {
@Test
public void logicTest() {
System.out.println("====使用代理模式前");
- IStudent iStudent = new StudentImpl();
- iStudent.save();
- iStudent.delete();
+ ISchool iSchool = new SchoolImpl();
+ iSchool.save();
+ iSchool.delete();
System.out.println();
- System.out.println("=====使用代理模式后");
- IStudent studentProxy = new StudentProxy(iStudent);
+ System.out.println("=====使用静态代理模式后");
+ ISchool studentProxy = new SchoolProxy(iSchool);
studentProxy.save();
studentProxy.delete();
}