DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Frameworks
  4. Inject Spring beans in AspectJ

Inject Spring beans in AspectJ

Marco Tedone user avatar by
Marco Tedone
·
Jul. 21, 11 · Interview
Like (0)
Save
Tweet
Share
13.04K Views

Join the DZone community and get the full member experience.

Join For Free

AspectJ is the most powerful AOP framework in the Java space; Spring is the most powerful enterprise development framework in the Java space. It's not surprise that combining the two should lead to wonderful things...In this article I'm going to show a very simple, yet complete, example where I have injected an AspectJ aspect with  a Spring bean.

Setting the Maven project

First, let's have a look at the Maven pom.xml showing all required dependencies and plugins:

<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>uk.co.jemos.experiments</groupId>
    <artifactId>aspectj-test</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>aspectj-test</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>3.0.5.RELEASE</spring.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.3.1</version>
                <executions>
                    <execution>
                        <id>waves-sources</id>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>uk.co.jemos.experiments.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2.1</version>
                <executions>
                    <execution>
                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
                        <phase>install</phase> <!-- bind to the packaging phase -->
                        <goals>
                            <goal>assembly</goal>
                        </goals>
                        <configuration>
                            <descriptors>
                                <descriptor>src/main/assembly/executable.xml</descriptor>
                                <descriptor>src/main/assembly/project.xml</descriptor>
                            </descriptors>
                            <outputDirectory>${project.build.directory}/executable</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
          <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.10</version>
        </dependency>
        <dependency>
          <groupId>javax.annotation</groupId>
          <artifactId>jsr250-api</artifactId>
          <version>1.0</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-beans</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>${spring.version}</version>
        </dependency>       
        <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>       
    </dependencies>
</project>

 

 

The business classes

The example builds on the one shown in the AspectJ in Action book 3rd Edition. It is very simple.

There is the business service which is in charge of delivering messages. The implementation looks like:

package uk.co.jemos.experiments;

import org.springframework.stereotype.Component;

@Component(MessageCommunicator.BEAN_NAME)
public class MessageCommunicator {

    public static final String BEAN_NAME = "uk.co.jemos.experiments.MessageCommunicator";

    public void deliver(String message) {

        System.out.println(message);
    }

    public void deliver(String person, String message) {

        System.out.println(person + ", " + message);
    }

}

 

I said it was very simple! The only thing to notice is that I have defined it as a Spring component.

Then there is the main class:

/**
 *
 */
package uk.co.jemos.experiments;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author mtedone
 *
 */
public class Main {

    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:appCtx.xml");

        MessageCommunicator communicator = ctx
                .getBean(MessageCommunicator.class);

        communicator.deliver("Hello World");

    }

}

 

The main class loads a Spring application context, it retrieves a MessageCommunicator bean and it invokes a business method on it.

The Spring configuration file

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   
    <context:component-scan base-package="uk.co.jemos.experiments" />

</beans>

Execution without aspects

Now, if I was to execute the code as it is, the output would be something like:

16-Jul-2011 18:50:19 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing

[...] Spring stuff...
Hello World

Adding an authentication aspect

Let's say that we want the user of the MessageCommunicator class to be authenticated each time a deliver(...) method is invoked. First I create the Authentication service:

package uk.co.jemos.experiments;

import org.springframework.stereotype.Component;

@Component(Authenticator.BEAN_NAME)
public class Authenticator {

    public static final String BEAN_NAME = "uk.co.jemos.experiments.Authenticator";

    public void authenticate() {
        System.out.println("User is authenticated");
    }

}

 

Nothing glamorous...Again the Authenticator has been declared as a Bean and that is important since we want to inject our Aspect with such Authenticator through Spring.

Then I create the AspectJ aspect:

package uk.co.jemos.experiments;

import javax.annotation.Resource;

public aspect SecurityAspect {



    @Resource(name = Authenticator.BEAN_NAME)
    private Authenticator authenticator;
   
   
    pointcut secureAccess() : execution(* MessageCommunicator.deliver(..));
   
    before() : secureAccess() {
        if (null == authenticator) {
            throw new IllegalStateException("Authenticator should not be null");
        }
        System.out.println("Checking and authenticating user...");
        authenticator.authenticate();
    }

}

Here we start seeing few interesting things, mainly that the aspect has been injected with an Authenticator bean.

The revisited Spring context looks now like the following:

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   
    <context:component-scan base-package="uk.co.jemos.experiments" />

    <bean id="securityAspect" class="uk.co.jemos.experiments.SecurityAspect" factory-method="aspectOf" />

</beans>

 

All I have done is to declare the aspect as a bean: this is possible because every aspect declares a static aspectOf method which returns an instance of the aspect itself. This is the doorway to injecting AspectJ aspects with Spring beans.

Running the modified version

If I run the Main class now, I get the following output:

16-Jul-2011 18:57:22 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@41ac1fe4: startup date [Sat Jul 16 18:57:22 BST 2011]; root of context hierarchy
16-Jul-2011 18:57:22 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [appCtx.xml]
16-Jul-2011 18:57:22 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@66100363: defining beans [uk.co.jemos.experiments.Authenticator,uk.co.jemos.experiments.MessageCommunicator,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,securityAspect]; root of factory hierarchy
Checking and authenticating user...
User is authenticated
Hello World

 

As you can see the aspect has kicked into action and the Authenticator object was indeed not null at the time of execution, which means that the Spring injection has worked.

 

 

From http://tedone.typepad.com/blog/2011/07/inject-beans-in-aspectj.html

Spring Framework AspectJ Aspect (computer programming)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Microservices Testing
  • 19 Most Common OpenSSL Commands for 2023
  • Using Swagger for Creating a PingFederate Admin API Java Wrapper
  • Host Hack Attempt Detection Using ELK

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: