标签: spring-aop

Spring AOP 方法拦截器与方法建议

我是 AOP 的新手,我试图理解方法拦截器和 MethodAdvice(即 MethodBeforeAdvice 或 MethodAfterAdvice)之间的区别。在我看来,两者都在做同样的事情,即在方法调用时调用。我们什么时候应该使用 MethodInterceptor 和 MethodAdvice。

spring spring-aop

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

将自定义注释建议应用于 spring data jpa 存储库

我正在研究 mysql 主从复制。我正在使用 spring data jpa(spring boot)。

我需要的是所有写入操作都转到主服务器,而只读操作则均匀分布在多个只读从服务器之间。

为此我需要:

使用特殊的 JDBC 驱动程序:com.mysql.jdbc.ReplicationDriver

在 URL 中设置复制:

spring:
    datasource:
        driverClassName: com.mysql.jdbc.ReplicationDriver
        url: jdbc:mysql:replication://127.0.0.1:3306,127.0.0.1:3307/MyForum?user=root&password=password&autoReconnect=true
        test-on-borrow: true
        validation-query: SELECT 1
    database: MYSQL
Run Code Online (Sandbox Code Playgroud)

需要关闭自动提交。(*) 连接需要设置为只读。

为了确保 JDBC Connection 设置为只读,我创建了一个注释和一个简单的 AOP 拦截器。

注解

package com.xyz.forum.replication;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; 

/**
 * Created by Bhupati Patel on 02/11/15.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReadOnlyConnection {
}
Run Code Online (Sandbox Code Playgroud)

拦截器

package com.xyz.forum.replication;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; …
Run Code Online (Sandbox Code Playgroud)

spring aspectj spring-aop spring-data-jpa spring-aspects

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

Spring AOP 参数


我对 Spring AOP 有疑问。我想在切入点中获取 Student 对象。但我的 JoinPoints 可以以任何优先级拥有该对象。
查看下面的代码片段,了解我创建的两个不同的连接点和切入点:

public Student createStudent(String s, Student student) {...}
public Student updateStudent(Student student, String s) {...}

@Before("args(..,com.hadi.student.Student)") 
public void myAdvice(JoinPoint jp) {
    Student student = null;
    for (Object o : jp.getArgs()) {
        if (o instanceof Student) {
            student = (Student) o;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码仅适用于第一个 JoinPoint。所以问题是如何创建一个切入点,该切点将在输入参数中针对 Student 的任何情况执行。
我无法使用下面的代码,它抛出runtimeException:
@Before("args(..,com.hadi.student.Student,..)")

我让代码变得容易理解,实际上我的切入点比这个大得多。所以请用args方式回答。

java spring spring-aop

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

Spring AOP中如何拦截元注解(annotated annotations)

假设我想找到所有用@Controller 注释的类,我会创建这个切入点:

    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void controllerPointcut() {}
Run Code Online (Sandbox Code Playgroud)

但是找不到那些用@RestController 注释的控制器。因为 RestController 本身是用@Controller 注释的。

关于如何查找使用 @Controller 或 @RestController 注释的类而无需创建两个 Pointcuts 的任何想法?


======编辑====我在这里的真正意图如下:

父注释:

public @interface ParentAnnotation {}
Run Code Online (Sandbox Code Playgroud)

子注释(用@ParentAnnotation 注释):

@ParentAnnotation 
public @interface ChildAnnotation {}
Run Code Online (Sandbox Code Playgroud)

A类:

@ParentAnnotation 
public class MyClassA {}
Run Code Online (Sandbox Code Playgroud)

B类:

@ChildAnnotation 
public class MyClassB {}
Run Code Online (Sandbox Code Playgroud)

现在我想通过@ParentAnnotation 找到MyClassA 和MyClassB。找到MyClassA是没有问题的,但是MyClassB是用@ParentAnnotation间接注释的,有没有通用的方法来处理这种情况?

spring annotations aspectj spring-aop

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

Spring AOP 中获取请求/响应正文和标头

我想在我的方面之前和之后获取请求/响应正文和标头(如果可用)或如何获取它们。

我的意思是我认为前面的注释应该适用于请求,

注释后应适用于响应。可 ?

到目前为止我已经尝试过:

我尝试了日志库,这对我来说非常复杂,我不知道如何使用它。所以我放弃了。

执行器可以做一些技巧,但我正在做额外的工作,比如端点调用多少次等,因此我不能使用执行器。

另外,我尝试获取至少如下所示的请求标头,但我认为该标头始终相同。我无法像 httpservetrequest 那样获得 httpservletresponse 。

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
Run Code Online (Sandbox Code Playgroud)

那么 request.getHeader("date")requestbody 呢?

如何获取请求体?响应主体?响应头?

我的方面文件:

@Aspect
@Component
public class AppAspect implements ResponseInfo{

    @Before("execution(@(@org.springframework.web.bind.annotation.RequestMapping *) * *(..))")
    public void loggingStartPointRequests(JoinPoint joinPoint) {

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();

}

@After("execution(@(@org.springframework.web.bind.annotation.RequestMapping *) * *(..))")
    public void loggingEndPointRequests(JoinPoint joinPoint) throws IOException {

    }

}
Run Code Online (Sandbox Code Playgroud)

我的控制器类:

@RestController
public class MainController {

    @GetMapping("/people") // 
    public ResponseEntity<Poeple> getAllPeople(@RequestParam(name = "page", required = false) Integer page,
            @RequestParam(name = …
Run Code Online (Sandbox Code Playgroud)

aop spring http spring-aop spring-boot-actuator

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

Spring AOP:为什么@After注释在Java、AspectJ中的@AfterThrowing之后执行?

我正在学习 AspectJ 注释,我认为 @After 注释在 @AfterThrowing 注释之前执行。但相反,它在它之后执行。为什么?

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(2)
public class MyDemoLoggingAspect {

    @After("execution(* com.luv2code.aopdemo.dao.AccountDAO.findAccounts(..))")
    public void afterFinallyFindAccountsAdvice(JoinPoint theJoinPoint) {
        
        // print out which method we are advising on
        String method = theJoinPoint.getSignature().toShortString();
        System.out.println("\n=====>>> Executing @After (finally) on method: " 
                            + method);
    
    }
    
    @AfterThrowing(
            pointcut="execution(* com.luv2code.aopdemo.dao.AccountDAO.findAccounts(..))",
            throwing="theExc")
    public void afterThrowingFindAccountsAdvice(
                    JoinPoint theJoinPoint, Throwable theExc) {
        
        // print out which method we …
Run Code Online (Sandbox Code Playgroud)

java aspectj spring-aop

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

为什么Spring AOP需要代理类?

AOP中代理类的责任是什么?这有什么作用?

java spring spring-aop

0
推荐指数
1
解决办法
791
查看次数

在Spring AOP中出现错误"ClassName类型的层次结构不一致"

package com.nit.aop.advices;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class LoggingBeforeAdvice implements MethodBeforeAdvice
{

    @Override
    public void before(Method arg0, Object[] arg1, Object arg2)
            throws Throwable {
        // TODO Auto-generated method stub

    }

}
Run Code Online (Sandbox Code Playgroud)

当我执行这个程序时,我得到错误 - "ClassName类型的层次结构是不一致的"所以现在我想删除此错误

java spring spring-aop

0
推荐指数
1
解决办法
3464
查看次数

在不与数据库对话的方法中使用 Spring 的 @Transactional 注释是否有意义?

我试图了解一个涉及 spring 声明性事务注释的项目。该函数的主体没有进行任何 JDBC 调用或调用 JPA 存储库方法。它所做的只是调用一些第三方 API 并转换它的结果,它甚至没有将响应保存在数据库中。所以根本没有数据库交互。

我的问题是是否值得在此方法上使用 @Transactional 注释?因为根据我的理解,@Transactional 仅有助于保持数据库的一致性。

spring spring-aop spring-transactions spring-boot

0
推荐指数
1
解决办法
392
查看次数

如何监控第三方库的方法执行?

我有任务以某种方式监视 logback 库中的方法调用。我开始用 spring aop 做这件事。因此,例如,我应该在 ch.qos.logback.classic.Logger 类中捕获所有方法的执行。这是我的方面:

@Aspect
@Configuration
public class LogbackAspect {

    @Before(value = "execution(* ch.qos.logback.classic.Logger.*(..))")
    public void getInfo(JoinPoint joinPoint) {
         System.out.println("+++++AOP " + joinPoint.getSignature().getName());
}
}
Run Code Online (Sandbox Code Playgroud)

但是暂时不行,那么,有没有可能用spring aop拦截方法执行呢?或者有一些更好的方法来做到这一点?

java aop spring spring-aop

0
推荐指数
1
解决办法
496
查看次数

作为Spring @Value()的默认值的异常

我是Java/Spring的新手.我需要从配置中读取一些值,但如果它不存在则应该失败.现在我有以下代码:

public class SomeClass {

    @Value("${some.property:#{null}}")
    private String someProperty;

    public void someMethod() throws Exception {
        if (someProperty == null) throw new AopConfigException("The property must be set");
    }

}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我需要添加额外的if块.我可以写那样的东西吗?

@Value("${some.property:#{throw new AopConfigException(\"The property must be set\")}}")
private String someProperty;
Run Code Online (Sandbox Code Playgroud)

要么

@Value("${some.property:#{throwException()}}")
private String someProperty;

private static void throwException() {
    throw new AopConfigException("The property must be set");
}
Run Code Online (Sandbox Code Playgroud)

立即失败

更新: 如果我没有使用下面建议的某个默认值,那么它对我来说仍然不会失败.我没有java.lang.IllegalArgumentException:

在此输入图像描述

java spring spring-aop spring-annotations

-3
推荐指数
1
解决办法
1569
查看次数