Избегайте выражения pointcut на месте в Spring AOP

Я использую Spring АОП. Я даю свои pointcuts как:

@Pointcut("execution(* com.demo.Serviceable+.*(..))")
public void serviceMethodCalls() {
}

Можно ли избежать выражения pointcut на месте в Spring AOP?


person Veera    schedule 20.04.2009    source источник


Ответы (4)


Это зависит от того, какой стиль АОП вы выберете для Spring. Поскольку вы придерживаетесь подхода, основанного на аннотациях, вы мало что можете получить, кроме наличия констант для выражений, расположенных во внешнем классе.

Это связано с тем, что стиль АОП на основе аннотаций @Aspect предназначен для совместного размещения где и что. Вы можете каким-то образом получить некоторую настраиваемость, используя абстрактный метод и привязав к нему pointcut.

@Aspect
public abstract class MyAspect {

  protected abstract pointcut();


  @Before("pointcut()")
  public void myAdviceMethod() {
    // Advice code goes here
  }
}


public class ConcreteAspect extends MyAspect {

  @Pointcut("execution(* com.acme.*.*(..))")
  protected pointcut() {
  )
}

Это возможно, но мне кажется довольно неудобным, поскольку разработчик должен знать, что @Pointcut требуется в методе. Если она забудет поставить его, он полностью рухнет.

Если вам нужна гибкость, позволяющая разделить рекомендации и точки, вам лучше придерживаться конфигурации на основе XML (см. документация Spring, например).

Своего рода человек посередине — это возможность связать ваш pointcut с пользовательской аннотацией и позволить пользователям решать, где его разместить и, следовательно, когда применить ваш совет. Документация Spring (глава 6.2.3.4) дает больше информации об этом.

С уважением, Олли

person Oliver Drotbohm    schedule 23.04.2009
comment
поэтому pointcut() должен быть защищен abstract void pointcut(); Наверное? - person wonhee; 19.06.2018

Вот как вы можете определить настраиваемый Spring AOP Advice с Java Config:

@Configuration
public class ConfigurableAdvisorConfig {

    @Value("${pointcut.property}")
    private String pointcut;

    @Bean
    public AspectJExpressionPointcutAdvisor configurabledvisor() {
        AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
        advisor.setExpression(pointcut);
        advisor.setAdvice(new MyAdvice());
        return advisor;
    }
}

class MyAdvice implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before method");
        Object result = invocation.proceed();
        System.out.println("After method");
        return result;
    }
}

Затем pointcut.property можно определить в файле application.properties.

person got_bainne    schedule 07.10.2016

это то, чего ты хочешь? aop на основе прокси: http://static.springframework.org/spring/docs/2.5.x/reference/aop-api.html пример

<bean id="settersAndAbsquatulateAdvisor" 
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
    <ref local="beanNameOfAopAllianceInterceptor"/>
</property>
<property name="patterns">
    <list>
        <value>.*set.*</value>
        <value>.*absquatulate</value>
    </list>
</property>

person silmx    schedule 20.04.2009
comment
пример: ‹bean id=settersAndAbsquatulateAdvisor class=org.springframework.aop.support.RegexpMethodPointcutAdvisor› ‹property name=advice› ‹ref local=beanNameOfAopAllianceInterceptor/› ‹/property› ‹property name=patterns› ‹list› ‹value›.* set.*‹/value› ‹value›.*absquatulate‹/value› ‹/list› ‹/property› ‹/bean› - person silmx; 20.04.2009

Выражение Pointcut введено в Spring 2.X, что эффективно позволяет вам сопоставлять места, в которые вы хотите вплести совет.

Вы также можете использовать старомодный способ Spring1.X, который заключается в создании ProxyFactoryBean (состоящего из 1 целевого объекта и, возможно, нескольких советов) через xml конфигурации spring, как показано ниже. Таким образом, вам не нужно возиться с выражением pointcut. Недостатком этого является то, что вы можете вплетать советы только в один целевой объект, а не в несколько.

Ниже приведен один типичный пример:

<bean id="personTarget" class="com.mycompany.PersonImpl">
    <property name="name"><value>Tony</value></property>
    <property name="age"><value>51</value></property>
</bean>

<bean id="myAdvisor" class="com.mycompany.MyAdvisor">
    <property name="someProperty"><value>Custom string property value</value></property>
</bean>

<bean id="person" 
    class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces"><value>com.mycompany.Person</value></property>

    <property name="target"><ref local="personTarget"/></property>
    <property name="interceptorNames">
        <list>
            <value>myAdvisor</value>
        </list>
    </property>
</bean>
person Daniel    schedule 09.01.2010