Target.java
Target
是被代理类,但却不需要像Service
一样实现某个接口
public class Target {
public User getUserById(int id) {
User user = new User(id);
System.out.println("Get " + user + " from database...");
return user;
}
}
Before.java
前置增强接口
public interface Before {
Object before(Object[] args);
}
After.java
后置增强接口
public interface After {
void after(Object... args);
}
BeforeAdvice.java
前置增强实现类,从缓存中获取对象
public class BeforeAdvice implements Before {
private static Map<Integer, User> caching = new ConcurrentHashMap<>();
public static Map<Integer, User> getCaching() {
return caching;
}
@Override
public Object before(Object[] args) {
if (args == null)
return null;
// in default, the first arg is key
int keyId = (int) args[0];
// find the cache object
if (caching.containsKey(keyId)) {
User cachedUser = caching.get(keyId);
System.out.println("Get " + cachedUser + " from cache...");
return cachedUser;
}
// can't find the cache object
return null;
}
}
AfterAdvice.java
后置增强实现类,把从数据库获取的对象添加到缓存中,以便下次从缓存中获取
public class AfterAdvice implements After {
@Override
public void after(Object... args) {
if (args == null)
return;
BeforeAdvice.getCaching().put((Integer) args[0], (User) args[1]);
}
}
CglibProxy.java
public class CglibProxy implements MethodInterceptor {
private Object targetObject;
private Before beforeAdvice;
private After afterAdvice;
public CglibProxy(Object targetObject, Before before, After after) {
this.targetObject = targetObject;
this.beforeAdvice = before;
this.afterAdvice = after;
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object obj = null;
if (beforeAdvice != null) {
obj = beforeAdvice.before(args);
// get 'obj' from cache
if (obj != null) {
return obj;
}
}
// get 'obj' from database
obj = method.invoke(targetObject, args);
if (afterAdvice != null) {
// storage the 'obj' in cache for next search
afterAdvice.after(args[0], obj);
}
// return the database_obj
return obj;
}
}
CglibProxyFactory.java
通过 CGLIB 动态代理生成代理对象
public class CglibProxyFactory {
public static Object getCglibProxy(Object target) {
Enhancer enhancer = new Enhancer();
// set Target as SuperClass
enhancer.setSuperclass(target.getClass());
// set callback function (which implements MethodInterceptor)
enhancer.setCallback(new CglibProxy(target, new BeforeAdvice(), new AfterAdvice()));
// create proxy object
return enhancer.create();
}
}
User.java
public class User {
private int id;
public User(int id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
'}';
}
}
Client.java
public class Client {
public static void main(String[] args) {
Target proxyObject = (Target) CglibProxyFactory.getCglibProxy(new Target());
// The first time: get from database & storage it in cache
proxyObject.getUserById(1);
// The second time: get from cache
proxyObject.getUserById(1);
}
}
运行结果