Commit ed930790 by 王仕雄

靜態代理兩種方式(類繼承,接口實現),動態代理兩種方式(jdk,cglib)

1 parent 65205260
......@@ -28,6 +28,13 @@
</properties>
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
......@@ -251,6 +258,13 @@
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- ureport2报表引擎 -->
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-console</artifactId>
<version>2.2.8</version>
</dependency>
<!-- xss过滤组件 -->
......@@ -259,6 +273,19 @@
<artifactId>jsoup</artifactId>
<version>1.9.2</version>
</dependency>
<!-- 多数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!--war包部署需要-->
<!--<dependency>-->
......
package com.bootdo.common.utils.proxy.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGLIBDynamicProxy implements MethodInterceptor {
/**
*
*   * 生成代理对象   * @param cla 被代理的类   * @return 代理对象  
*/
public Object bind(Class cla) {
// 获取CGLIB增强类对象
Enhancer enhancer = new Enhancer();
// 设置对哪个类进行增强
enhancer.setSuperclass(cla);
// 设置哪个类为代理类,代理类必须实现MethodInterceptor接口
enhancer.setCallback(this);
// 生成代理对象并返回(根据之前的设置来生成代理对象)
return enhancer.create();
}
/**
*
*   * 代理类逻辑方法   * @param proxy 被代理对象   * @param method 代理类执行的方法对象   * @param
* args 方法传参   * @param methodProxy 方法代理对象   * @return 方法执行结果   * @throws
* Throwable  
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("开始执行代理类逻辑");
System.out.println("执行完代理类逻辑,准备执行真实对象方法");
// 调用真实对象的方法
Object result = methodProxy.invokeSuper(proxy, args);
System.out.println("真实对象方法执行完毕");
return null;
}
}
package com.bootdo.common.utils.proxy.cglib;
public class CglibTest {
public void justSayHello(){
System.out.println("我打印啦!");
}
}
package com.bootdo.common.utils.proxy.cglib;
/**
*
* @ClassName: Client
* @Description: 代理测试类-動態代理-cglib
* @author wangsx
* @date 2020年5月21日
*
*/
public class Client {
public static void main(String[] args) throws Exception{
try {
//创建代理类对象
CGLIBDynamicProxy cglibProxyExample = new CGLIBDynamicProxy();
//通过代理类获取CglibTest类的代理对象
CglibTest cglibTest =(CglibTest)cglibProxyExample.bind(CglibTest.class);//绑定管理,确定代理哪个类
//由代理类执行真实对象方法
cglibTest.justSayHello();
}catch(Exception e){
e.printStackTrace();
}
}
}
package com.bootdo.common.utils.proxy.jdk;
/**
*
* @ClassName: Client
* @Description: 代理测试类-動態代理-jdk
* @author wangsx
* @date 2020年5月21日
*
*/
public class Client {
public static void main(String[] args) {
// // 保存生成的代理类的字节码文件
// System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
// jdk动态代理测试
Subject subject = new JDKDynamicProxy(new RealSubject()).getProxy();
subject.doSomething();
}
}
package com.bootdo.common.utils.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKDynamicProxy implements InvocationHandler {
private Object target;
public JDKDynamicProxy(Object target) {
this.target = target;
}
/**
* 获取被代理接口实例对象
* @param <T>
* @return
*/
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Do something before");
Object result = method.invoke(target, args);
System.out.println("Do something after");
return result;
}
}
package com.bootdo.common.utils.proxy.jdk;
public class RealSubject implements Subject {
@Override
public void doSomething() {
System.out.println("RealSubject do something");
}
}
package com.bootdo.common.utils.proxy.jdk;
public interface Subject {
void doSomething();
}
package com.bootdo.common.utils.proxy.staticcls;
/**
* 注意事项,代理增强时,不能改变原有业务代码的封装,继承方式..缺点:类爆炸
*
* @ClassName: ProxyTest
* @Description: 代理测试类-靜態代理-類繼承
* @author wangsx
* @date 2020年5月6日
*
*/
public class Client {
public static void main(String[] args) {
UserDaoImpl userDao = new UserDaoImpl();
userDao.query("张三");
System.out.println();
//静态代理-继承方式 增加查询时间
UserDaoImpl userDao2 = new LogUserDaoImpl();
userDao2.query("张三");
System.out.println();
//静态代理-继承方式 增加查询人
UserDaoImpl userDao3 = new LogFinalUserDaoImpl();
userDao3.query("张三");
System.out.println();
}
}
package com.bootdo.common.utils.proxy.staticcls;
public class LogFinalUserDaoImpl extends LogUserDaoImpl {
@Override
public void query(String name) {
System.out.println("当前查询人="+name);
super.query(name);
}
}
package com.bootdo.common.utils.proxy.staticcls;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogUserDaoImpl extends UserDaoImpl {
@Override
public void query(String name) {
System.out.println("代理增强,当前查询时间="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
super.query(name);
}
}
package com.bootdo.common.utils.proxy.staticcls;
public class UserDaoImpl {
//默认查询只打印查询姓名
public void query(String name) {
System.out.println("name="+name);
}
}
package com.bootdo.common.utils.proxy.statiinterface;
/**
* 注意事项,代理增强时,不能改变原有业务代码的封装,接口方式..缺点:类爆炸
*
* @ClassName: ProxyTest
* @Description: 代理测试类-靜態代理-接口實現
* @author wangsx
* @date 2020年5月6日
*
*/
public class Client {
public static void main(String[] args) {
UserDaoImpl userDao = new UserDaoImpl();
userDao.query("张三");
System.out.println();
//静态代理-接口方式,增加查询时间
UserDao userDao2 = new LogUserDaoImpl(userDao);
userDao2.query("张三");
System.out.println();
//静态代理-接口方式,增加查询人
UserDao userDao3 = new LogFinalUserDaoImpl(userDao2);
userDao3.query("张三");
System.out.println();
}
}
package com.bootdo.common.utils.proxy.statiinterface;
public class LogFinalUserDaoImpl implements UserDao {
private UserDao userDao;
public LogFinalUserDaoImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void query(String name) {
System.out.println("当前查询人="+name);
userDao.query(name);
}
}
package com.bootdo.common.utils.proxy.statiinterface;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogUserDaoImpl implements UserDao {
private UserDao userDao;
public LogUserDaoImpl(UserDao userDao) {
this.userDao = userDao;
}
public void query(String name) {
System.out.println("当前查询时间="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
userDao.query(name);
}
}
package com.bootdo.common.utils.proxy.statiinterface;
public interface UserDao {
public void query(String name);
}
package com.bootdo.common.utils.proxy.statiinterface;
public class UserDaoImpl implements UserDao{
//默认查询只打印查询姓名
public void query(String name) {
System.out.println("name="+name);
}
}
package com.bootdo.common.utils.search;
public class FibonacciSearch {
/**
* @param args
*/
public final static int MAXSIZE = 20;
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] f = fibonacci();
for (int i : f) {
System.out.print(i + " ");
}
System.out.println();
int[] data = { 1, 5, 15, 22, 25, 31, 39, 42, 47, 49, 59, 68, 88 };
int search = 42;
int position = fibonacciSearch(data, search);
System.out.println("值" + search + "的元素位置为:" + position);
}
/**
* 斐波那契数列
*
* @return
*/
public static int[] fibonacci() {
int[] f = new int[20];
int i = 0;
f[0] = 1;
f[1] = 1;
for (i = 2; i < MAXSIZE; i++) {
f[i] = f[i - 1] + f[i - 2];
}
return f;
}
public static int fibonacciSearch(int[] data, int key) {
int low = 0;
int high = data.length - 1;
int mid = 0;
// 斐波那契分割数值下标
int k = 0;
// 序列元素个数
int i = 0;
// 获取斐波那契数列
int[] f = fibonacci();
// 获取斐波那契分割数值下标
while (data.length > f[k] - 1) {
k++;
}
// 创建临时数组
int[] temp = new int[f[k] - 1];
for (int j = 0; j < data.length;j++) {
temp[j] = data[j];
}
// 序列补充至f[k]个元素
// 补充的元素值为最后一个元素的值
for (i = data.length; i < f[k] - 1; i++) {
temp[i] = temp[high];
}
for (int j : temp) {
System.out.print(j + " ");
}
System.out.println();
while (low <= high) {
// low:起始位置
// 前半部分有f[k-1]个元素,由于下标从0开始
// 则-1 获取 黄金分割位置元素的下标
mid = low + f[k - 1] - 1;
if (temp[mid] > key) {
// 查找前半部分,高位指针移动
high = mid - 1;
// (全部元素) = (前半部分)+(后半部分)
// f[k] = f[k-1] + f[k-1]
// 因为前半部分有f[k-1]个元素,所以 k = k-1
k = k - 1;
} else if (temp[mid] < key) {
// 查找后半部分,高位指针移动
low = mid + 1;
// (全部元素) = (前半部分)+(后半部分)
// f[k] = f[k-1] + f[k-1]
// 因为后半部分有f[k-1]个元素,所以 k = k-2
k = k - 2;
} else {
// 如果为真则找到相应的位置
if (mid <= high) {
return mid;
} else {
// 出现这种情况是查找到补充的元素
// 而补充的元素与high位置的元素一样
return high;
}
}
}
return -1;
}
}
package com.bootdo.common.utils.search;
import java.util.Date;
public class SearchTest {
public static void main(String[] args) {
int [] a = randomCommon(1,10000,8000);
int b = 4889;
Date d1 = new Date();
System.out.println("普通查找,结果为:"+sequentialSearch(a,b));
Date d2 = new Date();
System.out.println("普通查找,耗时:"+(d2.getTime()-d1.getTime()));
Date d3 = new Date();
System.out.println("哨兵查找,结果为:"+sequentialSearchSentry(a,b));
Date d4 = new Date();
System.out.println("哨兵查找,耗时:"+(d4.getTime()-d3.getTime()));
// int k=0;
// for(int i=0;i<10;i++) {
// System.out.println("外循环.."+i);
// for(int j=i;j<10;j++) {
// System.out.println((k++)+"..."+j);
// }
// }
}
//顺序查找---普通,找到了返回数组中的下标,没找到返回-1
private static int sequentialSearch(int [] a, int key) {
for(int i=0;i<a.length;i++) {
if(a[i]==key) {
return i;
}
}
return -1;
}
//顺序查找---哨兵,找到了返回数组中的下标,没找到返回-1
private static int sequentialSearchSentry(int [] a, int key) {
a[0]=key;
int i= a.length-1;
while(a[i]!=key) {
i--;
}
return i==0?i-1:i;
}
/**
* 随机指定范围内N个不重复的数
* 最简单最基本的方法
* @param min 指定范围最小值
* @param max 指定范围最大值
* @param n 随机数个数
*/
public static int[] randomCommon(int min, int max, int n){
if (n > (max - min + 1) || max < min) {
return null;
}
int[] result = new int[n];
int count = 0;
while(count < n) {
int num = (int) (Math.random() * (max - min)) + min;
boolean flag = true;
for (int j = 0; j < n; j++) {
if(num == result[j]){
flag = false;
break;
}
}
if(flag){
result[count] = num;
count++;
}
}
return result;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!