是否可以使JSF FacesServlet与AspectJ一起使用?

时间:2015-05-17 09:48:02

标签: maven jsf tomcat jsf-2 aspectj

我试图编写示例应用程序,显示在tomcat和JSF上运行的AspectJ的FacesServlet之间的集成。我创建了两个项目:

1)JSF项目:

pom.xml

<dependencies>
        <!-- JSF 2.0 dependencies -->
    <dependency>
        <groupId>com.pac</groupId>
        <artifactId>aspectj-lib</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

<build>
    <finalName>JavaServerFaces</finalName>

    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <configuration>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>com.pac</groupId>
                        <artifactId>aspectj-lib</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>

ManagedBean

@ManagedBean
@SessionScoped
public class HelloBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;

    public String getName() {
        test();
        return name;
    }

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

    public int test(){
        System.out.println("Test is invoked");
        return 10;
    }

}

2)aspectj-lib包含所有方面

pom.xml

<dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.8.2</version>
        </dependency>
  </dependencies>

  <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
  </build>

TestAspect.aj

public aspect TestAspect {
    pointcut t(): execution(public !static * *(..));

    int around() : t() {
        System.out.println("Test string");    
        int v = proceed();
        return v * 2;
    }
}

所以,我希望在调用test()时该方面应该发挥作用。但它没有,我在控制台输出中看到的只有:

Test is invoked
Test is invoked
Test is invoked
Test is invoked
该方面中定义的

Test string未被打印。

如何整合JSFAspectJ?有文件吗?

也许我应该在web.xml/faces-config.xml中添加额外的配置信息,或者创建另一个配置文件以使其正常工作?

1 个答案:

答案 0 :(得分:1)

Documentation reference

答案很简单。我们所要做的就是 替换 编译时编织与加载时织入。加载时编织意味着我们将在JVM尝试加载它们时编织我们的类。替换是必要的,因为编译时编织和加载时编织彼此不兼容。所以,假设我们有两个项目:

aspects-lib
    |---pom.xml
    |---src/main/aspect
             |---TestAspect.aj   -- aspect itself


JavaServerFaces
    |---pom.xml
    |---src/main/java
    |          |---TestBean.java    -- The bean which methods we want to intercept
    |---src/main/resources
    |          |---META-INF/aop.xml -- That file configures the load-time weaving
    |---src/main/webapp
               |
        webpages, omited

我们现在考虑一下配置。

aop.xml(加载时织入配置):

<aspectj>
  <aspects>
    <aspect name="fully.qualified.ascpect.name"/>
  </aspects>

  <weaver options="-verbose">
    <include within="package.you.want.to.weave.*"/>
  </weaver>
</aspectj>

aspect-lib/pom.xml

 <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.8.2</version>
        </dependency>
  </dependencies>

  <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <!-- IMPORTANT!!!!!! -->
                    <!-- DISABLING COMPILE TIME WEAVING -->
                    <outxml>true</outxml>
               <XterminateAfterCompilation>true</XterminateAfterCompilation>
                    <!-- DISABLING COMPILE TIME WEAVING -->
                </configuration>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
  </build>

JavaServerFaces/pom.xml

    <dependency>
            <!-- aspect-lib dependency -->
    </dependency>

    <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>aspectj-maven-plugin</artifactId>
         <version>1.7</version>
         <configuration>
            <outxml>true</outxml>
            <XterminateAfterCompilation>true</XterminateAfterCompilation>
            <aspectLibraries>
                <aspectLibrary>
                    <!-- your aspect lib -->
                </aspectLibrary>
            </aspectLibraries>
         </configuration>

         <executions>
             <execution>
                 <goals>
                     <goal>compile</goal>
                 </goals>
             </execution>
         </executions>
    </plugin>

还有一件事:您应该将以下选项添加到JVM中,以便允许servlet-container/app-server perfrom加载时编织:

-javaagent:pathto/aspectjweaver.jar

应将相应的jar文件添加到服务器的资源中。