我正在尝试使用SpringBoot和AOP记录异常。使用gradlew和Java 1.8。
Main.java
@SpringBootApplication
@EnableAutoConfiguration
@EnableAspectJAutoProxy
public class Main implements CommandLineRunner {
@Override
public void run(String... args) {
try{
ThrowingExample();
}catch(Exception e){
System.out.println("This message is printed");
}
}
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
static void ThrowingMethod() throws FileNotFoundException {
throw new FileNotFoundException();
}
}
AfterThrowAspect.java
@Component("AfterThrowAspect")
@Aspect
public class AfterThrowAspect {
@AfterThrowing(pointcut = "execution(* *.*.*(..))", throwing = "exception")
public void logAfterThrowing(Exception exception) {
System.out.println("Not Printed @AfterReturning:"+new Date());
System.out.println("Exception caught:"+ exception.getMessage());**
}
}
我的Gradle文件是
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'idea'
mainClassName = 'learn.Main'
repositories {
maven {
url "http://repo1.maven.org/maven2"
}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
configurations {
aspectjweaver
}
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
compile("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
compile "org.springframework:spring-webmvc:4.+"
compile "org.springframework:spring-aop:4.+"
compile "org.springframework.boot:spring-boot-starter-web:1.+"
compile "org.aspectj:aspectjrt:1.+"
compile "org.slf4j:slf4j-api:1.+"
aspectjweaver "org.aspectj:aspectjweaver:1.+"
runtime configurations.aspectjweaver.dependencies
}
方法logAfterThrowing在异常后永远不会被调用。我正在使用Intellj,ide说ThrowingMethod是AdvisedMethod。
我是Java新手。在网上四处看看让我觉得这应该有用但不会发生。它编译并运行但是AfterThrowAspect.java中的logAfterThrowing从未调用过。所有文件都在同一层次结构和相同的包中。
答案 0 :(得分:1)
修改
我想我发现你的代码存在问题。 Spring面向方面的编程只适用于由spring容器维护的bean。 由于抛出异常的方法是静态方法,因此spring无法拦截此。
How to intercept static methods in Spring?
解决方案
在服务或组件中定义您的方法并自动装配它。
工作示例repo https://github.com/mirmdasif/springmvc/tree/master/aopexceptionhandling
完整答案
首先,在服务bean中定义您的方法
@Service
public class ExceptionalService {
public void thorowException() throws Exception {
throw new Exception();
}
}
第二次,而不是@component
注释,您应该在AspectJ类中使用@configuration
。另外,在切入点中使用正确的包名称
@Aspect
@Configuration
public class ErrorInterceptor {
@AfterThrowing(pointcut = "execution(* net.asifhossain.*.*(..))", throwing = "ex")
public void errorInterceptor(Exception ex) {
ex.printStackTrace();
}
}
第三次自动连接服务并使用它。
@SpringBootApplication
@EnableAspectJAutoProxy
public class AopExampleApp implements CommandLineRunner {
@Autowired
ExceptionalService service;
@Override
public void run(String... args) throws Exception {
try {
service.thorowException();
thorowException();
} catch (Exception ex) {
// Do nothing Since aop will log the answer
}
}
public static void main(String[] args) {
SpringApplication.run(AopExampleApp.class);
}
public static void thorowException() throws Exception {
throw new Exception();
}
}
我创建了一篇博客文章,其中详细介绍了如何使用Spring的面向方面编程来处理异常。 您可以通过以下链接访问它