Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring AOP creates extra bean

I 'm playing with Spring AOP.

Here is a simple class

public class CModel extends Car {
    private double torqueMeasure = 1;

    public CModel() {
        System.out.println(" C-Model constructor");        
    }
}

And Spring configuration is like this

<aop:config>
    <aop:aspect ref="audit">
        <aop:before pointcut="execution(* com.test.main..*(..))" method="firstControl"/>
            ...
    </aop:aspect>
</aop:config>

Ok now; when i add aop:config and intercepts CModel then Spring calls CModel constructor twice. It means Spring creates 2 CModel object, right ?

If I delete AOP config then Spring creates only one CModel object.

Any idea why it is like this ?

Thanks.

like image 386
Lurtz Avatar asked Nov 01 '11 14:11

Lurtz


People also ask

Does Spring AOP use AspectJ?

In Spring AOP, aspects are implemented using regular classes (the schema-based approach) or regular classes annotated with the @Aspect annotation (the @AspectJ style). Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception.

How does AOP work in Spring boot?

AOP (Aspect-Oriented Programming) is a programming pattern that increases modularity by allowing the separation of the cross-cutting concern. These cross-cutting concerns are different from the main business logic. We can add additional behavior to existing code without modification of the code itself.

How does Spring create proxies?

During application startup, the Spring framework instantiates the target bean, BookController , and creates a proxy of the target class. The proxy of the target class is created only once. If the target class doesn't implement any interface, the proxy is of type CglibAopProxy .

What is the use of @aspect annotation in Spring?

@After declares the after advice. It is applied after calling the actual method and before returning result. @AfterReturning declares the after returning advice. It is applied after calling the actual method and before returning result.


2 Answers

Though I'm not sure, my guess is that spring first instantiates the regular class, and then makes a CGLIB proxy, which is a subclass. Note that for initialization you should use @PostConstruct, which is guaranteed to be used once.

To verify my hypothesis, add a breakpoint in the constructor and see when it is invoked - one of the times it should be right after the CModel$EnhancedByCGLIB something

like image 118
Bozho Avatar answered Sep 22 '22 20:09

Bozho


When Spring creates a proxy to your class, it will use CGLIB to generate a class that subclasses CModel. The net affect is your constructor will be called twice.

Check out the Spring documentation for more detail (specifically the third bullet): http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-proxying

As a side note, Spring will use the JDK proxying mechanism if your class implements an interface -- and the JDK proxying mechanism will not call your constructor.

like image 43
wmkoch Avatar answered Sep 20 '22 20:09

wmkoch