Java springaop日志线程方法
是否有任何方法可以实现类的AOP日志记录到公共方法,该类Java springaop日志线程方法,java,multithreading,concurrency,aop,Java,Multithreading,Concurrency,Aop,是否有任何方法可以实现类的AOP日志记录到公共方法,该类实现可运行并由ExecutorService运行 螺纹类 @Component @Scope("prototype") public class FileProcessor implements Runnable { private final LinkedBlockingQueue<File> filesQueue; private final GiftCertificateMapper certificateMap
实现可运行并由ExecutorService运行
螺纹类
@Component
@Scope("prototype")
public class FileProcessor implements Runnable {
private final LinkedBlockingQueue<File> filesQueue;
private final GiftCertificateMapper certificateMapper;
private final File errorFolder;
private static final ReentrantLock LOCK = new ReentrantLock();
private static final Logger LOGGER = LoggerFactory.getLogger(FileProcessor.class);
public FileProcessor(LinkedBlockingQueue<File> filesQueue, GiftCertificateMapper certificateMapper,
File errorFolder) {
this.filesQueue = filesQueue;
this.certificateMapper = certificateMapper;
this.errorFolder = errorFolder;
}
@Override
public void run() {
File file = null;
try {
while ((file = filesQueue.poll(100, TimeUnit.MILLISECONDS)) != null) {
processFile(file);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.warn("File thread was interrupted");
} catch (IOException e) {
LOGGER.error("Error processing file {} \n{}", file.getAbsolutePath(), e);
}
}
public void processFile(File file) throws IOException {
if (file != null) {
try {
ObjectMapper objectMapper = new ObjectMapper();
List<GiftCertificate> certificates = Arrays.asList(objectMapper.readValue(file, GiftCertificate[].class));
certificateMapper.insertList(certificates);
file.delete();
} catch (JsonParseException | UnrecognizedPropertyException | InvalidFormatException | DataIntegrityViolationException e) {
moveFileToErrorFolder(file);
}
}
}
private void moveFileToErrorFolder(File file) throws IOException {
try {
LOCK.lock();
Files.move(Paths.get(file.getAbsolutePath()), getPathForMovingFile(file), StandardCopyOption.ATOMIC_MOVE);
} finally {
LOCK.unlock();
}
}
private Path getPathForMovingFile(File fileForMove) {
File fileList[] = errorFolder.listFiles();
int filesWithSameNameCounter = 0;
if (fileList != null && fileList.length > 0) {
for (File file : fileList) {
if (file.getName().contains(fileForMove.getName())) {
filesWithSameNameCounter++;
}
}
}
return filesWithSameNameCounter > 0 ?
Paths.get(errorFolder.getAbsolutePath(), "(" + filesWithSameNameCounter + ")" + fileForMove.getName()) :
Paths.get(errorFolder.getAbsolutePath(), fileForMove.getName());
}
}
在SpringAOP中,无法拦截内部方法调用
在代码共享中,即使方法processFile()
是公共的,也会从run()
调用它。这是一个自引用/内部方法调用,无法拦截
详情请参阅
由于Spring的AOP框架基于代理的特性,在
根据定义,目标对象不被拦截。对于JDK
代理,只能调用代理上的公共接口方法
拦截
截取对实现Runnable
的类的所有外部方法调用的切入点表达式如下
@Around("this(java.lang.Runnable) && within(com.epam.esm.processor..*)")
public Object logFileProcessing(ProceedingJoinPoint pjp) throws Throwable {
try {
return pjp.proceed();
} finally {
//log
System.out.println("****Logged");
}
}
作用域指示符in()
限制了应用建议的范围
切入点@Pointcut(“execution(*com.epam.esm.processor.FileProcessor.processFile(java.io.File))”)
是有效的,如果发生外部方法调用,它就会工作
希望这有帮助。请举例说明您希望建议的课程类型。该类注册为Springbean吗?你是怎么做到的?为什么没有呢?@SotiriosDelimanolis补充说,没有,它没有注册为Springbean@SotiriosDelimanolis如果对象未注册为SpringBean,它将不起作用?不,通知仅应用于spring应用程序上下文中的bean。@我的应用程序的SotiriosDelimanolis editi结构,但processFile方法上的切入点仍然不起作用,但若我在运行时改变方法,它会工作,那个么问题在哪里呢?你能帮个忙吗?已经得到并实现了加载时间编织,但无论如何都是ty。
@Around("this(java.lang.Runnable) && within(com.epam.esm.processor..*)")
public Object logFileProcessing(ProceedingJoinPoint pjp) throws Throwable {
try {
return pjp.proceed();
} finally {
//log
System.out.println("****Logged");
}
}