开发者

Spring AOP: advice is not triggered

开发者 https://www.devze.com 2023-04-12 07:41 出处:网络
Trying to design simple aspect,that will print word \"logg\" to console,when any of public methods executed.

Trying to design simple aspect,that will print word "logg" to console,when any of public methods executed.

aspect:

@Aspect
public class LoggingAspect {

    @Pointcut("execution(public * *(..))")
    public void publicServices() {
    };

    @Before("publicServices()")
    public开发者_JS百科 void logg() {
        System.out.println("logg");
    }

}

xml config:

    <context:component-scan base-package="aspectlogging" /> 
    <aop:aspectj-autoproxy/>
    <bean id="loggingAspectHolder" class="aspectlogging.LoggingAspect"/>

simple bean:

package aspectlogging;
@Component
    public class TestableBean {

        private String name;

        public String getName() {
            return name;
        }

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

test:

public class TestLogging {
    public static void main(String[] args) {
        TestableBean tb = new TestableBean();
        tb.setName("yes");
        tb.getName();
    }
}

I expect,that result of running of TestLogging will be "logg" word in console,and no output returned. Do I understand AOP correctly in this case?


With @Around advice, you need to have a ProceedingJoinPoint pjp argument to the advising method and to call pjp.proceed() at the point in the advisor when you want the wrapped method to be called. It's easier to use @Before advice really, when what you've done will otherwise work just fine.


[EDIT]: Also, you must let Spring construct your beans for you instead of directly calling new. This is because the bean object is actually a proxy for your real object (which sits inside it). Because your target object doesn't implement an interface, you will need to have the cglib library on your classpath in addition to the Spring libraries. (Alternatively, you can go with using AspectJ fully, but that requires using a different compiler configuration.)

To create your beans, you first need to create a Spring context and then query that for the bean instance. This means you change from:

TestableBean tb = new TestableBean();

To (assuming you're using Spring 3, and that your XML config is in "config.xml" somewhere on your classpath):

ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
TestableBean tb = context.getBean(TestableBean.class);

The rest of your code remains the same (after adjusting for import statements and possibly additional dependencies).


Not quite sure on this one, but maybe you need to use a spring managed TestableBean to have spring AOP pick up the method call.

edit: of course, you can't use @Around the way that you provided - but this subject has been addressed by another answer, so it's omitted here.

edit2: If you need help on how to get a spring managed bean, please feel free to ask. but since you already got your aspect bean set up, I believe you can handle this :)

edit3: Hehe. Ok.. maybe not :)

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

will load your application context. Load beans from there by calling:

TestableBean testableBean = (TestableBean )ctx.getBean("testableBean ");

Define the TestableBean just like you did with your Aspect bean.

edit4: Now I'm pretty sure that the fault is the non-spring managed bean.

Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ as there is no requirement to introduce the AspectJ compiler / weaver into your development and build processes. If you only need to advise the execution of operations on Spring beans, then Spring AOP is the right choice. If you need to advise domain objects, or any other object not managed by the Spring container, then you will need to use AspectJ.

Taken from: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号