0

Spring プロジェクトで AOP を有効にしようとしています。@RequestMapping が完了した後にコード (セッションクリーニング) を実行したい。これが私のapplicationContext.xmlです(参照されたリソースをロードするだけです

<?xml version="1.0" encoding="UTF-8" standalone="no"?><beans 
xmlns="http://www.springframework.org/schema/beans"  
xmlns:aop="http://www.springframework.org/schema/aop"  
xmlns:context="http://www.springframework.org/schema/context"  
xmlns:jee="http://www.springframework.org/schema/jee" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.springframework.org/schema/beans       
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">

    <!-- ******************************************************************** -->
    <!-- Include context files from different layers -->
    <!-- ******************************************************************** -->
    <import resource="classpath:appname-security-context.xml"/>
    <import resource="classpath:appname-service-context.xml"/>
    <import resource="classpath:appname-dao-context.xml"/>

</beans>

セキュリティ コンテキスト:

<?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:security="http://www.springframework.org/schema/security" 
    xmlns:lang="http://www.springframework.org/schema/lang"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/security    http://www.springframework.org/schema/security/spring-security-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<http auto-config="true">
<intercept-url pattern='/pages/login.jsp' />
<intercept-url pattern="/secure/*" access="IS_AUTHENTICATED_REMEMBERED" />
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/pages/login.jsp" authentication-failure-url="/pages/login.jsp?login_error=true"  /> 
        <logout logout-success-url="/pages/logout-redirect.jsp" invalidate-session="true" />
        <remember-me key="appnameRMKey" user-service-ref="userDetailsService" />
    </http>
    <authentication-manager alias="authenticationManager" >
    <authentication-provider user-service-ref='userDetailsService' >
        <password-encoder hash="plaintext"/>
    </authentication-provider>
    </authentication-manager>

    <beans:bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <beans:property name="rolePrefix" value="ROLE_" />
        <beans:property name="dataSource" ref="springSecurityDataSource" />
        <beans:property name="usersByUsernameQuery" value="SELECT username,password,enabled FROM Users WHERE username = ?" />
        <beans:property name="authoritiesByUsernameQuery" value="SELECT u.username, a.authorityname FROM Users u JOIN Users_Authorities ua on u.id = ua.user_id JOIN Authorities a on ua.authorities_id = a.id WHERE u.username = ?" />
    </beans:bean>   

    <!-- ******************************************************************** -->
    <!-- Apply security for all beans where security was set -->
    <!-- ******************************************************************** -->

    <global-method-security jsr250-annotations="enabled" proxy-target-class = "true" secured-annotations="enabled">
        <protect-pointcut expression="execution(* appname.UsersDAO.*(..))" access="IS_AUTHENTICATED_REMEMBERED"/>
        <protect-pointcut expression="execution(* appname.AuthoritiesDAO.*(..))" access="IS_AUTHENTICATED_REMEMBERED"/>
    </global-method-security>
</beans:beans>

私のサービスコンテキスト:

<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:lang="http://www.springframework.org/schema/lang"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-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/jee 
        http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
        http://www.springframework.org/schema/lang
        http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
    <!-- ******************************************************************** -->
    <!-- Scan for service layer annotated beans -->
    <!-- ******************************************************************** -->
<context:component-scan base-package="appname" scoped-proxy="interfaces" />
<aop:config  proxy-target-class="true">
    </aop:config>
    <aop:aspectj-autoproxy proxy-target-class="true">
    </aop:aspectj-autoproxy>
    <!-- ******************************************************************** -->
    <!-- Mark bean transactions as annotation driven -->
    <!-- ******************************************************************** -->
    <tx:annotation-driven transaction-manager="transactionManager" />

</beans>

私のWebコンテキスト:(短さのために省略されたBean定義!!)

<mvc:annotation-driven/>
    <mvc:default-servlet-handler/>    
    <tx:annotation-driven transaction-manager="transactionManager" />
    <bean id="multipartResolver" class="org.skyway.spring.util.web.binary.ModelBindingMultipartResolver" />
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
    <bean id="streamedBinaryContentView" class="org.skyway.spring.util.web.binary.ModelAttributeStreamer" />
    <bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver" />
    <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/pages/" />
    </bean>
    <bean id="iPhoneUserAgentViewResolver" class="org.skyway.spring.util.viewresolution.UserAgentViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="agentSubstring" value="iPhone" />
    <property name="prefix" value="/WEB-INF/iphone/" />
    <property name="order" value="0" />
    </bean><bean id="webInfViewResolver" class="org.skyway.spring.util.viewresolution.AbsolutePathViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="order" value="-1" />
    </bean>
    <context:component-scan base-package="appname" scoped-proxy="interfaces" />
    <aop:config  proxy-target-class="true">
    </aop:config>
    <aop:aspectj-autoproxy proxy-target-class="true">
    </aop:aspectj-autoproxy>
    </beans>

これはアスペクトクラスのインターフェースです

package appname;
import it.pstmarche.model.HibernateSessionFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public interface SessionInterceptor {

@Pointcut("execution(public * appname.ImplantManager+.*(..))")
public void pc() ;

@Before("pc()")
public void print();
}

実装は簡単 です @Before("pc()") public void print(){ System.out.println("About to make call to print Hello World" }

次のような他の表現も試しました。

  • @Pointcut("execution(@org.springframework.web.bind.annotation.RequestMapping public * appname.*(..))")
  • その他多数

運がない。問題は式ではなく (すでに 10 ~ 15 の型を試しました...)、コンテキストで考慮されていないクラスだと思い始めました。

答えについては、次の点を考慮してください。

  • appname という名前は、明らかに意図されたものです。
  • aop:config と aop:aspectj-autoproxy を挿入するのは試しにすぎません。他のスレッドで、applicationContext によってロードされるすべてのファイルで構成を有効にする必要があることも読んだからです。私も1つだけ挿入しようとしましたが、結果はありませんでした
  • コントローラーには、注釈付きインターフェース + 注釈付き実装があります。インターフェイスに注釈を付けたり、完全に削除したりせずに試してみましたが、結果はありませんでした

助けはありますか?:)

編集: axtavt への応答で..申し訳ありませんが、web.xml を追加するのを忘れていました。ここにその一部があります

<servlet>
<description>context-servlet</description>
    <servlet-name>appname Servlet</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:appname-web-context.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

web-context.xml ファイルを介して contextConfigLocation を正しくロードします。すいません忘れてました(-_-;)

EDIT2:axtavtの提案により、私の間違いに続いて答えが得られました!ありがとう!

4

1 に答える 1

0

AOPは、コンテキストごとに構成されます。

2つのコンテキストがあります。ルートWebアプリケーションコンテキスト(applicationContext.xmlインポートされた構成ファイルを含む)と、DispatcherServletコントローラーBeanが宣言されているのアプリケーションコンテキストです。

<aop:aspectj-autoproxy>したがって、コントローラにアスペクトを適用するには、サーブレット固有のコンテキストに追加する必要があります。

<context:component-scan>また、異なるコンテキストで同じ基本パッケージを使用しないように注意してください。 @Serviceが2回構築されるを参照してください。

于 2012-04-20T10:17:50.047 に答える