Java Spring:Spring是否可以访问在Spring管理的bean中私人创建的对象?

Java Spring:Spring是否可以访问在Spring管理的bean中私人创建的对象?,java,spring,spring-aop,Java,Spring,Spring Aop,我有一个Java类,如下所示: public class Foo{ public void doSomething(){ StageA a = new StageA(); StageB b = new StageB(); StageC c = new StageC(); a.execute(); b.execute(); c.execute(); } } 现在,假设我不能真正编辑这个类本身,我是否仍然可以使用SpringA

我有一个Java类,如下所示:

public class Foo{
   public void doSomething(){
     StageA a = new StageA();
     StageB b = new StageB();
     StageC c = new StageC();
     a.execute();
     b.execute();
     c.execute();
   }
}

现在,假设我不能真正编辑这个类本身,我是否仍然可以使用SpringAOP在
execute
方法周围应用日志
?(大概不使用aspect4j)

您可以记录方法及其所需的时间(用于性能),但我认为您无法记录方法正在执行的操作

发件人:

环绕建议:围绕连接点(如方法调用)的建议。这是最有力的建议。Around建议可以在方法调用前后执行自定义行为。它还负责选择是继续连接点,还是通过返回自己的返回值或引发异常来缩短建议的方法执行


如果您在方法内部使用log4j记录器,您可以通过配置log4j来记录方法正在做什么

(可能不使用aspect4j)

-->Spring内部使用
aspectJ

检查参考和示例编辑:
我不认为在不更改Foo或Stage类的情况下记录每个“execute”方法的执行是可能的。因为舞台。。。类不是由容器管理的。您只能在doSomething方法开始执行时记录日志(如果Foo类由Spring容器管理),您无法控制它的执行流

如果您的类是由Spring容器管理的,那么您可以很容易地做到这一点。你应该简单地为舞台写下SpringAOP的“环绕”方面。。。类,而不是Foo类

下面是一个简单日志方面的示例:

@Component
@Aspect
@Order(value=2)
public class LoggingAspect {

    @Around("execution(* com.blablabla.server..*.*(..))")
    public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable{
        final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
        Object retVal = null;

        try {
            StringBuffer startMessageStringBuffer = new StringBuffer();

            startMessageStringBuffer.append("Start method ");
            startMessageStringBuffer.append(joinPoint.getSignature().getName());
            startMessageStringBuffer.append("(");

            Object[] args = joinPoint.getArgs();
            for (int i = 0; i < args.length; i++) {
                startMessageStringBuffer.append(args[i]).append(",");
            }
            if (args.length > 0) {
                startMessageStringBuffer.deleteCharAt(startMessageStringBuffer.length() - 1);
            }

            startMessageStringBuffer.append(")");

            logger.trace(startMessageStringBuffer.toString());

            StopWatch stopWatch = new StopWatch();
            stopWatch.start();

            retVal = joinPoint.proceed();

            stopWatch.stop();

            StringBuffer endMessageStringBuffer = new StringBuffer();
            endMessageStringBuffer.append("Finish method ");
            endMessageStringBuffer.append(joinPoint.getSignature().getName());
            endMessageStringBuffer.append("(..); execution time: ");
            endMessageStringBuffer.append(stopWatch.getTotalTimeMillis());
            endMessageStringBuffer.append(" ms;");

            logger.trace(endMessageStringBuffer.toString());
        } catch (Throwable ex) {
            StringBuffer errorMessageStringBuffer = new StringBuffer();

             // Create error message 
             logger.error(errorMessageStringBuffer.toString(), e)

            throw ex;
        }

        return retVal;
    }
}
@组件
@面貌
@顺序(值=2)
公共类日志方面{
@大约(“执行(*com.blabla.server..**(..)”)
公共对象日志方法(ProceedingJoinPoint joinPoint)抛出可丢弃的{
final Logger Logger=LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
Object retVal=null;
试一试{
StringBuffer startMessageStringBuffer=新StringBuffer();
附加(“开始方法”);
startMessageStringBuffer.append(joinPoint.getSignature().getName());
startMessageStringBuffer.append(“”);
对象[]args=joinPoint.getArgs();
对于(int i=0;i0){
startMessageStringBuffer.deleteCharAt(startMessageStringBuffer.length()-1);
}
startMessageStringBuffer.append(“)”;
trace(startMessageStringBuffer.toString());
秒表秒表=新秒表();
秒表。开始();
retVal=joinPoint.procedure();
秒表;
StringBuffer endMessageStringBuffer=新的StringBuffer();
endMessageStringBuffer.append(“Finish方法”);
endMessageStringBuffer.append(joinPoint.getSignature().getName());
endMessageStringBuffer.append((..);执行时间:);
endMessageStringBuffer.append(stopWatch.getTotalItemillis());
endMessageStringBuffer.append(“ms;”);
trace(endMessageStringBuffer.toString());
}捕获(可丢弃的ex){
StringBuffer errorMessageStringBuffer=新建StringBuffer();
//创建错误消息
logger.error(errorMessageStringBuffer.toString(),e)
掷骰子;
}
返回返回;
}
}

是的,您可以使用名为
execute()
切入点定位方法编写一个
@Around
建议,如下所示:

@Around("execution(* execute(..))")
public Object execute(ProceedingJoinPoint pjp) throws Throwable
{
    // Log statements before the call;

    Object obj = pjp.proceed();

    // Log statements after the call;

    return obj;
}

如果不是由spring容器管理,我如何为Stage类编写方面呢?对不起,愚蠢的错误。不能为非容器管理的类编写SpringAOP方面。这就是你的情况。现在我将考虑另一种方法来实现这一点,我不认为在不更改Foo类的情况下记录每个“execute”方法的执行情况是可能的。因为舞台。。。类不是由容器管理的。您只能在doSomething mwthod开始执行时记录日志(如果Foo类由Spring容器管理),您无法控制它的执行流。它可以用于非Spring管理的对象吗?据我所知,spring围绕bean创建了一个代理,因此它实际上是在调用代理,而不是实际的对象。它本身只对spring管理的对象起作用。您可以使用
@Configurable
注释限定Stage对象,这样即使使用
new
操作符创建对象,它们也可以成为spring管理的对象。然后,
@Around
方面将对execute方法起作用。