gpt4 book ai didi

java - 静态查找需要@Transactional但没有它的方法

转载 作者:行者123 更新时间:2023-12-01 14:36:10 26 4
gpt4 key购买 nike

为了避免数据库连接泄漏,可以配置 c3p0 让您知道它们何时发生,并指出问题代码:

<property name="unreturnedConnectionTimeout" value="900"/>  <!-- seconds -->
<property name="debugUnreturnedConnectionStackTraces" value="true"/>

最好在部署之前捕获它们。也就是说,在构建时静态捕获它们。似乎可以 1) 识别 DAO 类型的类,无论是这样注释还是通过 hbm 文件,然后 2) 向上跟踪调用树并标记未标记为 @Transactional 的方法。即使存在一些误报,这也是帮助消除此问题的有用工具。 IntelliJ 和 Eclipse 等 IDE 已经知道如何查找方法的调用者。

有没有一个开源工具可以做这样的事情?即使它没有执行第一步,手动识别 DAO 也很容易。这是从自动化解决方案中获益最多的第二部分。

最佳答案

我在 Spring 应用程序中遇到了类似的问题,并编写了一个在应用程序启动时运行的 bean 处理器,并在初始化后检查每个 bean。它不是编译时解决方案,但假设您在生产之前在某个地方运行应用程序,您将有机会找到缺少相关注释的方法。

它查找带有 @Service 注释的类,迭代该类实现的接口(interface),并检查每个接口(interface)的方法。它查找没有定义任何方法级安全性的方法,或者具有自定义 @Unsecured 注释的方法,这表明我们已经发现该方法缺乏安全性,但确定它不需要安全性。任何缺乏安全性@Unsecured注释的方法都会被记录。

以下代码曾一度有效,但用于较旧版本的 Spring。我不知道它是否适用于 Spring 3.x,但如果不能,类似的方法应该仍然有效。您可能需要调整检查逻辑以满足您的需求(例如,查找具有不同类级注释的类、检查类本身的方法而不是类实现的接口(interface)中的方法等)。请注意,我的方法没有尝试遍历调用树,因此您可能会得到更多误报(即并非所有服务方法最终都会调用 DAO 方法)。

public class UnsecuredServiceMethodProcessor implements BeanPostProcessor {
private static final Logger logger = LogManager.getLogger(UnsecuredServiceMethodProcessor.class);
private final MethodSecurityInterceptor interceptor;

public UnsecuredServiceMethodProcessor(MethodSecurityInterceptor interceptor) {
this.interceptor = interceptor;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
Class<?> beanClass = bean.getClass();
if (logger.isInfoEnabled()) {
logger.info("checking bean " + beanName + " of type " + beanClass.getName());
}
for (Class<?> interfaceClass: beanClass.getInterfaces()) {
checkClass(beanClass, interfaceClass);
}

return bean;
}

/**
* @param beanClass
* @param interfaceClass
*/
private void checkClass(Class<?> beanClass, Class<?> interfaceClass) {
if (interfaceClass.isAnnotationPresent(Service.class)) {
if (logger.isDebugEnabled()) {
logger.debug("found service implementation: " + interfaceClass + " on " + beanClass);
}
for (Method method: interfaceClass.getMethods()) {
if (!method.isAnnotationPresent(Unsecured.class)) {
if (logger.isDebugEnabled()) {
logger.debug("checking " + method.getName());
}
MethodSecurityMetadataSource msms = interceptor.getSecurityMetadataSource();
Collection<ConfigAttribute> atts = msms.getAttributes(method, interfaceClass);
if (atts == null || atts.size() == 0) {
logger.warn("unsecured method: " + method.getDeclaringClass().getName() + "." + method.getName());
}
}
}
}
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}

}

您需要在应用程序上下文中显式定义这种类型的 bean,或者添加 @Component 类级注释并扫描它。

关于java - 静态查找需要@Transactional但没有它的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16472073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com