import java.util.ArrayList;
import java.util.List;
/**
* 装饰器模式: 侧重于对目标类中核心逻辑的扩展, 依然是以目标类为中心
* 代理模式 : 侧重于对目标类的访问限制于处理,或者对其添加一些重用性且与 核心业务逻辑无关的功能, 例如日志.
*/
public class ProxyModel {
}
interface IDao{
void add(Object o);
void delete(Object o);
void update(int id,Object o);
Object find(int id);
}
class SimpleDao implements IDao{
private List<Object> mDataBase = new ArrayList<>();
@Override
public void add(Object o) {
mDataBase.add(o);
}
@Override
public void delete(Object o) {
mDataBase.remove(o);
}
@Override
public void update(int id,Object o) {
mDataBase.remove(id);
mDataBase.add(id,o);
}
@Override
public Object find(int id) {
return mDataBase.get(id);
}
}
class DaoProxy implements IDao{
private IDao iDao;
public DaoProxy() {
}
public DaoProxy(IDao iDao) {
this.iDao = iDao;
}
private void beginTransaction(){
System.out.println("开始操作数据库");
}
private void commit(){
System.out.println("结束操作数据库");
}
@Override
public void add(Object o) {
this.beginTransaction();
iDao.add(o);
this.commit();
}
@Override
public void delete(Object o) {
this.beginTransaction();
iDao.delete(o);
this.commit();
}
@Override
public void update(int id, Object o) {
this.beginTransaction();
iDao.update(id,o);
this.commit();
}
@Override
public Object find(int id) {
this.beginTransaction();
Object o = iDao.find(id);
this.commit();
return o;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
/**
* 动态代理: 相对于静态代理, 动态代理中的代理类不需要事先与目标类相同的接口, 而且不依赖于接口的具体实现, 理论上可以代理所有类的所有方法. 但因为要考虑到涉及到的业务, 所以要求面向接口代理.
* 实现机制: 运行时创建一个虚拟的代理类, 在代理的目标方式实际执行时, 通过java的反射技术获取到该防范对象, 并在执行前后后添加需要的操作, 这需要实现一个`InvocationHandler接口
*/
public class ProxyModel {
public static void main(String[] args) {
SimpleDao simpleDao = new SimpleDao();
IDao proxy = new DaoProxy().createProxy(simpleDao);
proxy.add("ss");
}
}
interface IDao {
void add(Object o);
void delete(Object o);
void update(int id, Object o);
Object find(int id);
}
class SimpleDao implements IDao{
private List<Object> mDataBase = new ArrayList<>();
@Override
public void add(Object o) {
mDataBase.add(o);
}
@Override
public void delete(Object o) {
mDataBase.remove(o);
}
@Override
public void update(int id,Object o) {
mDataBase.remove(id);
mDataBase.add(id,o);
}
@Override
public Object find(int id) {
return mDataBase.get(id);
}
}
class DaoProxy {
/*这里需要注意, 返回值只能是一个接口, 而不能使具体的实现类. */
public IDao createProxy(IDao target) {
/*此方法生成的虚拟类是根据目标的Class文件拿到的父类接口生成的, 因此不能强制转换成实现类 */
return (IDao) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beginTransaction();
Object invoke = method.invoke(target, args);
commit();
return invoke;
}
});
}
private void beginTransaction() {
System.out.println("读写开始前,开启数据库!");
}
private void commit() {
System.out.println("读写结束,关闭数据库!");
}
}
/**
* 不关心接口的实现逻辑, 只需要取到备操作类即可.
*/
public class ProxyModel {
public static void main(String[] args) {
IDao proxy = new LogProxy().createProxy(SimpleDao.class);
proxy.add("item");
proxy.delete("asd");
proxy.update(1,"asd");
}
}
interface IDao {
void add(Object o);
void delete(Object o);
void update(int id, Object o);
Object find(int id);
}
class SimpleDao implements IDao{
@Override
public void add(Object o) {
System.out.print("添加: "+o.toString()+" ");
}
@Override
public void delete(Object o) {
System.out.print("删除: "+o.toString()+" ");
}
@Override
public void update(int id,Object o) {
System.out.print("更新: "+id+" "+o.toString()+" ");
}
@Override
public Object find(int id) {
System.out.print("查找: "+id+" ");
return null;
}
}
class LogProxy {
public <T> T createProxy(Class<T> target) {
return (T) Proxy.newProxyInstance(target.getClassLoader(), target.getInterfaces(),
(proxy, method, args) -> {
System.out.print("开始输出日志------->");
System.out.print("调用方法:" + method.getName() + makeArgsText(args));
method.invoke(target.newInstance(),args);
System.out.print("<-------日志输出结束");
System.out.println();
return null;
});
}
private String makeArgsText(Object[] args) {
StringBuilder builder = new StringBuilder();
builder.append(", 共有").append(args.length).append("个参数: ");
for(Object item : args) {
builder.append(item.toString()).append(" & ");
}
return builder.toString();
}
}
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 如果目标类没有实现接口, 那么`Spring AOP`会选择使用`CGLIB`来动态代理目标类.
* CGLIB(Code Generation Library), 是一个代码生成的类库, 可以在运行时动态的生成某个类的子类.
* CGLIB是通过继承的方式做的动态代理, 因此如果某个类被标记为Final,那么它是无法使用CGLIB做动态代理的.
*/
class SimpleDao {
public void add(Object o) {
System.out.println("添加: " + o.toString() + " ");
}
public void delete(Object o) {
System.out.println("删除: " + o.toString() + " ");
}
public void update(int id, Object o) {
System.out.println("更新: " + id + " " + o.toString() + " ");
}
public Object find(int id) {
System.out.println("查找: " + id + " ");
return null;
}
}
class MyMethodInterceptor implements MethodInterceptor {
/**
* sub:cglib生成的代理对象
* method:被代理对象方法
* objects:方法入参
* methodProxy: 代理方法
*/
@Override
public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("======插入前置通知======");
Object object = methodProxy.invokeSuper(sub, objects);
System.out.println("======插入后者通知======");
return object;
}
}
class Client {
public static void main(String[] args) {
// 通过CGLIB动态代理获取代理对象的过程
Enhancer enhancer = new Enhancer();
// 设置enhancer对象的父类
enhancer.setSuperclass(SimpleDao.class);
// 设置enhancer的回调对象
enhancer.setCallback(new MyMethodInterceptor());
// 创建代理对象
SimpleDao proxy = (SimpleDao) enhancer.create();
// 通过代理对象调用目标方法
proxy.add("add");
}
}