当前位置: 首页 > 知识库问答 >
问题:

在Spring框架私有方法中使用AspectJ进行加载时编织

柯镜
2023-03-14

我构建了一个应用程序来测试围绕类注入日志信息(进入和退出)。我使用Spring构建了它,并使用以下示例构建它。

http://static.springsource.org/spring/docs/2.5.5/reference/aop.html#aop-aj ltw公司

它现在工作得很好,但我有2个问题:

  • 当日志围绕方法编织时,不包括私有方法。在Spring的xml设置中是否有允许编织私有方法的设置,还是有其他方法可以解决这个问题?
  • 我必须包含要在META-INF/aop.xml中编织的所有包才能工作。是否有一个设置要使用,以便可以为项目中创建的所有类编织日志信息,而无需将包名称添加到aop.xml.

下面我介绍了使用的所有代码和xml。正如我所说的,除了上述两个问题外,一切都很好。请帮助我。

应用程序。Java语言

package se.jpab.application;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

@Service
public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "spring.xml" });
        Client client = (Client) appContext.getBean("client");   
        Location clientLocation = (Location) appContext.getBean("location");        

//      Set all values
        clientLocation.setAdress1("Adress 1");
        clientLocation.setAdress2("Adress 2");
        clientLocation.setBox("N/A");
        clientLocation.setCity("City of Dallas");

        client.setName("John Doe");
        client.setUrl("http://www.url.com"); 
        client.setLocation(clientLocation);


 //     Print out all values        

        System.out.println(client.getName());        
        System.out.println(client.getUrl());
        System.out.println(client.getLocation().getAdress1());
        System.out.println(client.getLocation().getAdress2() + " " + client.getLocation().getCity());

    }
}

client.javase.jpab.application;

import org.springframework.stereotype.Service;

@Service
public class Client {

    String name;
    String url;
    Location location;
    //Constructors
    public Client(String custName, String custUrl, Location custLocation){
        name = custName;
        url = custUrl;  
        location = custLocation;
    }

    public Location getLocation() {
        return location;
    }

    public void setLocation(Location location) {
        this.location = location;
    }

    public Client(){

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {      
        this.name = name;
        printThis(name);

    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void printThis(String inStr) {
        System.out.println("PRIVAT METOD");
        System.out.println("Inkommand sträng --> " + inStr);
    }   


}

我ocation.java

package se.jpab.application;

import org.springframework.stereotype.Service;

@Service
public class Location {

    String city;
    String adress1;
    String adress2;
    String box;

    //Constructors  
public Location (String city, String adress1, String adress2, String box){

    this.city = city;
    this.adress1 = adress1;
    this.adress2 = adress2;
    this.box = box; 

}
public Location (){

}
public String getCity() {
    return city;
}
public void setCity(String city) {
    this.city = city;
}
public String getAdress1() {
    return adress1;
}
public void setAdress1(String adress1) {
    this.adress1 = adress1;
}
public String getAdress2() {
    return adress2;
}
public void setAdress2(String adress2) {
    this.adress2 = adress2;
}
public String getBox() {
    return box;
}
public void setBox(String box) {
    this.box = box;
}   
}

aop.xml

    <!DOCTYPE aspectj PUBLIC
        "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver options=" -showWeaveInfo">
        <!-- only weave classes in our application-specific packages -->        
        <include within="se.jpab.application.*"/>
        <include within="se.jpab.aspect.*"/>
    </weaver>

    <aspects>
        <!-- weave in just this aspect -->        
        <aspect name="se.jpab.aspect.InjectLogg"/>
    </aspects>
</aspectj>

方面

package se.jpab.aspect;

import java.util.Arrays;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class InjectLogg {

    private static final Log fallbackLogger = LogFactory.getLog(InjectLogg.class);

    @Around("execution(public * se.jpab.application..*.*(..))")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
                Object invoker = pjp.getThis();
                Log logger;

                logger = LogFactory.getLog(getClassNameFrom(invoker.getClass()));

                // Start injecting logg messages on entering a method.
                logger.info("ENTERING: (" + pjp.getSignature().getName() + ")");
                try {
                    logger.info("ARGUMENTS: " + Arrays.toString(pjp.getArgs()) + ")");
                } catch (NullPointerException e) {
                    logger.info("ARGUMENTS: No arguments");
                }

                try {
                    // proceed to original method call
                    Object result = pjp.proceed();

                    // Injecting exiting messages after method is finished
                    logger.info("RESULT: " + result);
                    logger.info("EXITING: (" + pjp.getSignature().getName() + ")");

                    // Return the result of the method we are logging
                    return result;

                } catch (IllegalArgumentException e) {
                    // same with ThrowsAdvice
                    logger.info("Exception. Throws IllegalArgumentException");
                    throw e;
                }

    }

    private String getClassNameFrom(Class invokerClassName) {
        // Function that ....... To be continued JP

        // Add check for that string contains $$ and se.goteborg if not then
        // return fallback logger class.

        String[] classNameParts = invokerClassName.getName().split("$$");
        int positionOfPackageName = classNameParts[0].indexOf("se.jpab");
        String className = classNameParts[0].substring(positionOfPackageName);

        return className;
    }
}

Spring配置(Spring.xml)

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="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/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">


 <aop:aspectj-autoproxy proxy-target-class="true"/>
 <context:load-time-weaver/>
 <context:annotation-config />
 <context:component-scan base-package="se.jpab"/>


</beans>

共有1个答案

卢骏俊
2023-03-14

您的第一个问题:

当日志围绕方法编织时,不包括私有方法。在Spring的xml设置中是否有允许编织私有方法的设置,还是有其他方法可以解决这个问题?

如果您想编织私有方法,请使用完整的AsheJ和其中的特权方面,而不是Spring AOP。Spring手册说:

如果您的拦截需求包括受保护/私有方法甚至构造函数,请考虑使用Spring驱动的原生AsheJ编织而不是Spring基于代理的AOP框架。这构成了具有不同特征的不同AOP使用模式,因此在做出决定之前,请务必先熟悉编织。

您的第二个问题:

我必须包括所有要在META-INF/aop中编织的包。xml使其能够工作。是否有要使用的设置,以便可以为项目中创建的所有类编织日志信息,而无需将包名称添加到aop。xml。

您可以使用捕获一个包及其所有子包 语法,例如<代码>se。jpab。应用程序* 或甚至<代码>se。jpab* 。还可以使用布尔运算符组合多个条件。有关示例,请参阅AspectJ文档。

 类似资料:
  • 我将使用Spring AOP和AspectJ加载时编织来度量代码中特定的私有/受保护/公共方法的执行时间。 为此,我编写了以下注解,其中一个注解将对应该测量执行时间的方法进行注解: 我还写了以下几个方面: 我的Spring配置如下: 我还在项目的目录中放置了以下: 此外,我还向POM添加了以下Spring AOP和/或AspectJ特定的依赖项: null 对于带注释的public和protect

  • 如果我使用的是基于AspectJ的Spring AOP,那么我是否需要配置我的方面来使用加载时间编织?或者Spring AOP在使用基于AspectJ的方法时也支持运行时/编译时编织吗?

  • 我通过jUnit测试执行这个。我正在分叉执行,以便可以传入JavaAgent。 并设置了aop.xml文件 生成的日志看起来一切都很好。 [junit]信息[main](DefaultContextLoadTimeWeaver.java:73)-找到Spring的JVM instrumentation代理[junit][AppClassLoader@12360BE0]信息AspectJ Weave

  • 当我设置Spring Ashej加载时间编织并通过关键字创建一个实例时,如下所示(下图)。事实证明,我无法访问构造函数中的依赖项。正如预期的那样,这一切都很好。执行顺序是 。现在,我可以访问构造函数中的依赖项。但问题是执行顺序:

  • 问题内容: 我正在将项目从Java 7迁移到Java 8,而我遇到的问题与使用进行AspectJ编织有关。 根据Haus文档,我可以使用在Java 6和7上运行的此插件成功配置编织。但是问题是,我还没有找到使用(和找到)支持Java 8的插件版本7的任何方法。我在这里看到插件7添加了Java 8支持,但是找不到使用它的方法。 这是我需要的配置插件: 我确认上述使用1.6版的代码对于Java 7可以