AOP 和 动态代理 切换DAO

本文介绍了一种利用动态代理和面向切面编程(AOP)技术来实现在运行时根据配置动态切换数据访问对象(DAO)的机制。通过这种方式可以灵活地选择使用不同的DAO实现,例如从Oracle DAO切换到Pgsql DAO。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1:AOP

package com.ai.dao;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;

import com.ai.core.springcontext.AppContext;
import com.ai.core.utils.PropertiesUtils;

public class DominoDaoInterceptor{

private String bundle = "com.ai.dao.DominoDaoInterceptor";
private Logger logger = Logger.getLogger(DominoDaoInterceptor.class);
private String usePgsqlDao = PropertiesUtils.getKey("PgsqlDaoUsed", bundle);

public void switchDao(ProceedingJoinPoint pjp) throws Throwable{
logger.info("Switch: " + pjp.getSignature().toLongString());

if("true".equalsIgnoreCase(usePgsqlDao)){
String calledMethod = pjp.getSignature().getName();
Object[] args = pjp.getArgs();
Class[] paraTypes = new Class[args.length];
for(int i = 0 ; i < args.length ; i++){
paraTypes[i] = args[i].getClass();
}
Method method = pjp.getTarget().getClass().getMethod(calledMethod, paraTypes);
String clazz = pjp.getTarget().getClass().getName();
String bean = PropertiesUtils.getKey(clazz.substring(clazz.lastIndexOf(".")+1), bundle);
Object object = null;
try{
object = AppContext.getApplicationContext().getBean(bean);
}catch(Exception e){
logger.error(e.getMessage());
logger.error("As it failed to switch, the origenal dao was used.");
pjp.proceed();
return;
}
method.invoke(object, args);
}else{
pjp.proceed();
}
}
}



2:动态代理

package com.ai.dao;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.apache.log4j.Logger;

import com.ai.core.springcontext.AppContext;
import com.ai.core.utils.PropertiesUtils;

public class DaoSwapper {

private static String BUNDLE = "com.ai.dao.DaoSwapper";
private static Logger logger = Logger.getLogger(DaoSwapper.class);
private static String usePgsqlDao = PropertiesUtils.getKey("PgsqlDaoUsed",
BUNDLE);

public static Object swap(Object object) {

if (!"true".equalsIgnoreCase(usePgsqlDao)) {
return object;
}
logger.info("Swap Dao: " + object.getClass());

DaoHandler handler = new DaoSwapper(). new DaoHandler(object);
return Proxy.newProxyInstance(object.getClass().getClassLoader(),
object.getClass().getInterfaces(), handler);
}

private class DaoHandler implements InvocationHandler {

private Object original;
private Object target;

public DaoHandler(Object obj) {
this.original = obj;
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

String targetBeanName = getTargetBeanName(original);
target = AppContext.getApplicationContext().getBean(targetBeanName);
return method.invoke(target, args);
}

private String getTargetBeanName(Object obj) {
String clazz = obj.getClass().getName();
clazz = clazz.substring(clazz.lastIndexOf(".") + 1);
return PropertiesUtils.getKey(clazz, BUNDLE);
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值