标签: spring-aop

实现审计跟踪 - Spring AOP vs.Hibernate Interceptor与DB Trigger

我在这个问题上找到了几个讨论主题 - 但没有任何内容在一个主题下对所有三种机制进行了比较.

所以这是我的问题......

我需要审核数据库更改 - 插入\ updates \删除到业务对象.

我可以想到三种方法来做到这一点

1)DB触发器

2)Hibernate拦截器

3)Spring AOP

(这个问题特定于Spring\Hibernate\RDBMS-我猜这对java\c#或hibernate \nhibernate-是中立的 - 但如果你的答案依赖于C++或Java或者hibernate的具体实现 - 请注明)

选择其中一种策略有哪些优缺点?

我不是要求实现细节.-这是一个设计讨论.

我希望我们可以将其作为社区维基的一部分

database audit hibernate spring-aop

13
推荐指数
1
解决办法
1万
查看次数

Spring AOP:如何获得建议方法的注释

我想用Spring/AOP和注释实现声明性安全性.正如您在下一个代码示例中所看到的,我使用了限制注释和参数"allowedRoles"来定义允许执行建议方法的人员.

    @Restricted(allowedRoles="jira-administrators")
        public void setPassword(...) throws UserMgmtException {             
               // set password code
               ...
        }
Run Code Online (Sandbox Code Playgroud)

现在,问题是在我的建议中我无法访问已定义的注释:

public Object checkPermission(ProceedingJoinPoint pjp) throws Throwable {

    Signature signature = pjp.getSignature();
    System.out.println("Allowed:" + rolesAllowedForJoinPoint(pjp));
            ...
}

private Restricted rolesAllowedForJoinPoint(ProceedingJoinPoint thisJoinPoint)
        {
            MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
            Method targetMethod = methodSignature.getMethod();

            return targetMethod.getAnnotation(Restricted.class);
        }
Run Code Online (Sandbox Code Playgroud)

上面的方法总是返回null(根本没有找到注释).有一个简单的解决方案吗?

我读了一些关于使用AspectJ代理的内容,但我不想使用这个代理.

java security spring spring-aop

13
推荐指数
3
解决办法
1万
查看次数

AspectJ加载时间weaver没有检测到所有类

我在"aspectj"模式下使用Spring的声明式事务(@Transactional注释).它在大多数情况下都可以完全像它应该的那样工作,但对于其中一个它没有.我们可以称之为Lang(因为这就是它实际上所称的).

我已经能够确定加载时间织布机的问题.通过打开aop.xml中的debug和verbose日志记录,它列出了所有正在编织的类.Lang根本没有在日志中提到有问题的类.

然后我在顶部放置了一个断点Lang,导致Eclipse在Lang加载类时挂起线程.当LTW编织其他类时,这个断点被击中!所以我猜测它要么编织也要Lang失败并且不输出,或者其他一些类有一个引用强制它Lang在实际有机会编织它之前加载.

我不确定如何继续调试这个,因为我无法以较小的规模重现它.有关如何继续的任何建议?


更新:其他线索也欢迎.例如,LTW实际上如何运作?似乎有很多魔法发生.是否有任何选项可以从LTW获得更多的调试输出?我目前有:

<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">
Run Code Online (Sandbox Code Playgroud)

我忘了汤姆之前提到它:弹簧剂被用来允许LTW,即InstrumentationLoadTimeWeaver.


根据Andy Clement的建议,我决定检查AspectJ变压器是否甚至通过了这门课程.我放了一个断点ClassPreProcessorAgent.transform(..),看起来这个Lang类甚至都没有到达那个方法,尽管它被与其他类(Jetty的WebAppClassLoader的一个实例)相同的类加载器加载.

然后我接着断了一个断点InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(..).甚至没有一个被击中Lang.我相信应该为所有加载的类调用该方法,无论他们使用什么类加载器.这开始看起来像:

  1. 我的调试有问题.可能Lang在Eclipse报告时没有加载
  2. Java bug?牵强附会,但我想它确实发生了.

接下来的线索:我打开了-verbose:class,看起来好像Lang 过早加载 - 可能是在变压器添加到Instrumentation之前.奇怪的是,我的Eclipse断点没有捕获到这个加载.

这意味着Spring是新的嫌疑人.在ConfigurationClassPostProcessor负载类中似乎有一些处理来检查它们.这可能与我的问题有关.


这些行ConfigurationClassBeanDefinitionReader导致Lang类被读取:

else if (metadata.isAnnotated(Component.class.getName()) ||
        metadata.hasAnnotatedMethods(Bean.class.getName())) {
    beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
    return true;
}
Run Code Online (Sandbox Code Playgroud)

特别是对类的metadata.hasAnnotatedMethods()调用getDeclaredMethods(),它加载该类中所有方法的所有参数类.我猜这可能不是问题的结束,因为我认为这些类应该被卸载.JVM是否可以出于不可知的原因缓存类实例?

java aop aspectj spring-aop

13
推荐指数
1
解决办法
5983
查看次数

测试Spring AOP方面

在编写方面时,如何测试它们是否匹配,以及在我需要时调用它们?

我正在使用@AspectSpring 2.5.6的声明.


我不关心功能,否则提取和测试.

java spring spring-aop

12
推荐指数
2
解决办法
1万
查看次数

如何为多个包指定单个切入点

我在基于spring mvc的应用程序中使用Aspect进行日志记录活动.我正在使用@controller注释来定义我的应用程序中的任何控制器.我在两个不同的包中有两个不同的控制器说

  • com.package1包含控制器1类,我们将其命名为AController
  • com.package2包含控制器2类,我们将其命名为BController

我可以通过使用将方面应用于一个特定的控制器包

<aop:config>
    <aop:pointcut id="pointcut1"
        expression="execution(* package1.*.*(..))"
        id="policy1" />
    <aop:aspect ref="aspect1" order="1">
        <aop:before pointcut-ref="pointcut1" method="before" arg-names="joinPoint" />
        <aop:after-returning returning="returnValue" arg-names="joinPoint, returnValue" pointcut-ref="pointcut1" method="after"  />
    </aop:aspect>
</aop:config>


<bean id="aspect1" class="com......aspectclass" />
Run Code Online (Sandbox Code Playgroud)

我的问题是如何指定在一个以上的不同包装的表达(*包1. ..(..))**.

现在我宣布为每个包在一个方面的一个单独的一个单独的切入点aop:before,并aop:after为每个切入点条目.但我认为这应该是定义多个包切入点的理想方式.

aop spring spring-aop pointcut aspect

12
推荐指数
2
解决办法
3万
查看次数

error引用的类型不是注释类型:

我有以下看点

@Around("execution(public * (@DisabledForBlockedAccounts *).*(..))" + " && @annotation(denyForTeam)")
public Object translateExceptionsDenySelectedAccount(ProceedingJoinPoint pjp, Deny deny) throws Throwable
{
    Account account = (Account) pjp.getArgs()[0];
    Account selectedAccount = (Account) pjp.getArgs()[1];

    if (ArrayUtils.contains(deny.value(), account.getRole()))
    {

        if (account.getType().equals(Type.CHEF) && !selectedAccount.getType().equals(Type.CHEF))
        {
            throw new IllegalAccessException("");
        }
    }
    return pjp.proceed();
}
Run Code Online (Sandbox Code Playgroud)

和这个注释:

@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface DenyForTeam
{

Role[] value();

}
Run Code Online (Sandbox Code Playgroud)

我得到错误:错误引用的类型不是注释类型:denyForTeam

为什么DenyForTeam没有注释?它标有@interface

aop spring spring-aop

12
推荐指数
2
解决办法
2万
查看次数

使用Spring AOP && MVC订购方面

我正在尝试使用Spring AOP和Spring MVC Controller.我有3个方面,并希望按特定顺序.为了做到这一点,我使用Ordered接口并实现getOrder方法:

@Aspect
@Component
public class LoggingAspect implements Ordered{

public int getOrder() {
System.out.println("Abra");
return 1;
}
Run Code Online (Sandbox Code Playgroud)

建议课程:

@Component
@Controller
public class HomeController {   
Run Code Online (Sandbox Code Playgroud)

切入点:

@Aspect
public class SystemArchitecture {

    @Pointcut("execution (* com.jajah.StorageManager.HomeController.*(..))")
    public void inHomeController(){}

    @Pointcut("execution (* com.jajah.StorageManager.HomeController.*(..))")
    public void loggable(){}

    @Pointcut("execution (* com.jajah.StorageManager.HomeController.*(..))")
    public void authenticated(){}

}
Run Code Online (Sandbox Code Playgroud)

组态:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <annotation-driven />
    <context:annotation-config /> 
    <aop:aspectj-autoproxy proxy-target-class="false"/>

    <beans:bean id="AuthenticationAspect" class="com.jajah.CommonAspects.SecurityAspects.OAuthAspect"/>
    <beans:bean id="ErrorHandlingAspect" …
Run Code Online (Sandbox Code Playgroud)

java spring spring-mvc spring-aop

12
推荐指数
1
解决办法
2万
查看次数

如何将HttpServletRequest注入Spring AOP请求(自定义场景)?

我知道围绕控制器方法编写AOP建议的标准方法,并且如果在控制器方法中声明,则可以访问HttpServletRequest arg.

但我的情况是我有一个翻译服务,目前是会话范围的维护用户的翻译区域设置.我觉得这使得服务状态有限,而且我不希望它是会话范围的,因为我认为它确实是Singleton.但是有多个地方调用了翻译服务方法,因此我不想更改签名以在这些方法中添加请求/语言环境.问题是翻译服务方法的所有调用者都无法访问HttpServletRequest(不是控制器方法)?我是否可以围绕翻译服务方法编写一个方面,并以某种方式神奇地访问HttpServletRequest,无论它是否在调用者的上下文中可用?

@Service
public class TranslationService {
    public void translate(String key) {
        ...
    }
}

@Aspect
@Component
public class LocaleFinder {
    @PointCut("execution(* TranslationService.translate(..))")
    private void fetchLocale() {}

    @Around("fetchLocale()") // in parameter list
    public void advice(JoinPoint joinpoint, HttpServletRequest request) { .... } 
}
Run Code Online (Sandbox Code Playgroud)

如果现在,translate的调用者没有HttpServletRequest,我不能在建议中得到请求吗?有解决方法吗?

spring-aop

12
推荐指数
1
解决办法
1万
查看次数

Spring方面如何在内部工作?

Say Service调用需要应用日志方面(注释)的Dao类.我想知道方面实际上是如何应用的.

根据我在服务对象下注入DAO时的理解,spring发现有一些方面(在这种情况下是日志记录)是为DAO配置的,因此它会注入代理对象而不是实际的目标对象.现在,当对DAO中的任何方法进行实际调用时,代理应用方面,然后调用实际的目标对象.那是对的吗 ?另外我相信这叫做跑步编织.

另一方面,可以使用加载时间编织(使用javaagent配置)完成相同的操作,其中对需要应用方面的类执行字节代码操作.所以代理不会在这里出现.

如果我错了,请纠正我,因为这是所有弹簧模块的基础?

java spring aspectj spring-aop

12
推荐指数
1
解决办法
8169
查看次数

Spring AOP更改方法参数的值,围绕建议

在使用Spring AOP执行之前,是否可以在某些检查的基础上更改方法参数值

我的方法

public String doSomething(final String someText, final boolean doTask) {
    // Some Content
    return "Some Text";
}
Run Code Online (Sandbox Code Playgroud)

建议方法

public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
    String methodName = methodInvocation.getMethod().getName();

    Object[] arguments = methodInvocation.getArguments();
    if (arguments.length >= 2) {
        if (arguments[0] instanceof String) {
            String content = (String) arguments[0];
            if(content.equalsIgnoreCase("A")) {
                // Set my second argument as false
            } else {
                // Set my second argument as true
            }
        }
    }
    return methodInvocation.proceed();
}
Run Code Online (Sandbox Code Playgroud)

请建议我设置方法参数值的方法,因为参数没有setter选项.

java spring spring-aop

12
推荐指数
3
解决办法
8998
查看次数

标签 统计

spring-aop ×10

spring ×7

java ×6

aop ×3

aspectj ×2

aspect ×1

audit ×1

database ×1

hibernate ×1

pointcut ×1

security ×1

spring-mvc ×1