How to enable autowire support within unmanaged class in spring using aspectj?

1.1k Views Asked by At

How can i setup spring / aspectj to autowire beans in classes that are not managed by the spring classloader system?

In my example i have added the @Configurable annotation to my unmanaged class and setup aspectj in order to generate the aspectj enhanced classes during compile time. I'm using JDK 1.8

The complete source code for a minimalistic example can be found here: https://github.com/Jotschi/spring-aspecj-compiletime-weaving

Within the example i have also added a custom aspect defintion in order to verify that aspectj is working. Spring has detected the aspect and the aspect is handled correctly. That way the only thing that remains is that the field is not autowired within my unmanaged class.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>de.jotschi</groupId>
    <artifactId>spring-aspecj-compiletime-weaving</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <spring.version>4.1.6.RELEASE</spring.version>
        <aspectj.version>1.8.5</aspectj.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Test dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

    <build>

        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>

                    <outxmlfile>META-INF/aop.xml</outxmlfile>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                    <complianceLevel>1.8</complianceLevel>
                    <source>1.8</source>
                    <target>1.8</target>
                    <forceAjcCompile>true</forceAjcCompile>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

unmanaged class:

package de.jotschi.test;

import static org.junit.Assert.assertNotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

@Configurable
public class UnmanagedClass {

    @Autowired
    private MessagerService messagerService;

    public UnmanagedClass() {
        // TODO Auto-generated constructor stub
    }

    public void test() {
        System.out.println("test called");
        assertNotNull("The service within the " + getClass().getSimpleName()
                + " class should not be null since the class was annotated with @Configurable and the field was autowired.", messagerService);
        messagerService.sayHello();
    }

    public void setService(MessagerService messagerService) {
        this.messagerService = messagerService;
    }

}

spring configuration:

package de.jotschi.test;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan(basePackages = { "de.jotschi" })
@EnableAspectJAutoProxy
public interface SpringTestConfiguration {

}

Update:

I updated my github project. It now includes the missing annotation and could be useful for someone who wants to setup aspectj + spring.

https://github.com/Jotschi/spring-aspecj-compiletime-weaving

1

There are 1 best solutions below

0
On BEST ANSWER

The solution was to add @EnableSpringConfigured to my SpringTestConfiguration class. Kudos to M. Deinum for pointing this out.