【问题标题】:Is it possible to make JSF FacesServlet work with AspectJ?是否可以使 JSF FacesServlet 与 AspectJ 一起工作?
【发布时间】:2015-07-28 21:58:28
【问题描述】:

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

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 没有被打印出来。

如何整合JSF 和AspectJ?有文档吗?

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

【问题讨论】:

  • 我不做 AspectJ,但根据我对 Spring 的经验,可能有必要使用 Spring 框架来连接 AspectJ 和 JSF。 AspectJ 和 Mojarra/JSF 提供托管执行上下文,只要这些上下文没有在某个地方相交,容器就不能为另一个容器做任何事情。如果您希望在 JSF 中实现 AOP,您应该考虑使用 CDI 提供的 AOP 而不是 AspectJ
  • @kolossus 不,这不是必需的。他只需要使用加载时编织而不是编译时编织。
  • 您可能应该在此处发布实现作为答案
  • @kolossus 我做到了。也许其他人可以使用它。

标签: maven jsf tomcat jsf-2 aspectj


【解决方案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 执行加载时编织:

-javaagent:pathto/aspectjweaver.jar

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

【讨论】:

    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 2015-02-19
    • 2018-12-15
    • 2012-02-04
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    相关资源
    最近更新 更多