[JAVA] call spring management bean from pojo

Thing you want to do

Since there are occasional cases where you want to call a spring management bean from a class that is not managed by spring, we will summarize the implementation method.

environment

java8 javaee7 spring4.3.9 eclipse4.6

Implementation plan

The service you want to call

The service you want to call


package com;

import org.springframework.stereotype.Service;

@Service
public class TestService {
    public void execute(){
        System.out.println("com.TestService#execute");
    }
}

Proposal 1 Static access to Spring management bean

Create a Spring management bean that holds ApplicationContext and access it from pojo via static method.

Spring management bean that holds ApplicationContext


package com.bridge;

import com.TestService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextBridge implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Autowired
    private TestService testService;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public static SpringContextBridge getInstance() {
        return applicationContext.getBean(SpringContextBridge.class);
    }

    public TestService getTestService() {
        return testService;
    }
}

pojo class


package com.bridge;

public class SpringContextBridgeClient {
    public static void main(String[] args) {
        SpringContextBridge.getInstance().getTestService().execute();
    }
}

Reference site https://blog.jdriven.com/2015/03/using-spring-managed-bean-in-non-managed-object/

Proposal 2 @Configurable

When compiling with AspectJ, replace the new part of the class with @Configurable (probably because I haven't checked the source).

@A class that becomes a spring management bean with Configurable


package com.configurable;

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

@Configurable
public class ConfigurableClient {

    @Autowired
    private TestService testService;

    public void execute() {
        testService.execute();
    }
}

pojo class


package com.configurable;

public class Configurable {
    public static void main(String[] args) {
        //Even if it is generated by new, it will be DI!
        new ConfigurableClient().execute();
    }
}

application-context.xml


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
					       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
					       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
					       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
    <context:spring-configured/>
    <context:component-scan base-package="com.configurable"/>
    <context:annotation-config />
</beans>

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>test1</groupId>
  <artifactId>artifact1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>artifact1</name>
  <url>http://maven.apache.org</url>

  <properties>
  	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<aspectj.version>1.6.12</aspectj.version>
    <spring.version>4.3.9.RELEASE</spring.version>
  </properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</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>javax.persistence</groupId>
			<artifactId>persistence-api</artifactId>
			<version>1.0.2</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>aspectj-maven-plugin</artifactId>
				<version>1.4</version>
				<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>
				<executions>
					<execution>
						<goals>
							<goal>compile</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<aspectLibraries>
						<aspectLibrary>
							<groupId>org.springframework</groupId>
							<artifactId>spring-aspects</artifactId>
						</aspectLibrary>
					</aspectLibraries>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

compile and run with maven


mvn clean compile
mvn exec:java -Dexec.mainClass="com.configurable.Configurable"

If you want to run it in eclipse instead of maven command

When you open pom.xml in eclipse, you should get the following error.

Execution of plugins not covered by lifecycle configuration: org.codehaus.mojo: aspectj-maven-plugin: 1.4: compile (execution: default, phase: compile)

You need to include AJDT so that you can use aspectj's compile.

AJDT installation

Now you can do it!

Reference site http://ryu-htn.hatenablog.com/entry/2013/04/25/151240 https://github.com/kenyattaclark/Spring-Configurable-Example https://tamasgyorfi.net/2013/11/13/spring-dependency-injection-configurable/

Reference site (eclipse error) http://tyru.hatenablog.com/entry/20140905/eclipse_lifecycle_error

Proposal 3 SpringBeanAutowiringInterceptor

Use JavaEE Interceptor and Spring SpringBeanAutowiringInterceptor. The following is an example of using the EJB class as a Spring managed bean. (Of course, it doesn't have to be EJB. @Stateless and @Remote are EJB annotations, so you can delete them.)

EJB class


package com.autowired;

import com.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
@Remote
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class TestEjb {

    @Autowired
    private TestService testService;

    public void execute() {
        testService.execute();
    }
}

Evaluation

Recommended Posts

call spring management bean from pojo
Call Chain from Chain in Spring Integration
Call Java from JRuby
Spring bean life cycle
1. Start Spring framework from 1
Try Spring Boot from 0 to 100.
Spring Bean Validaiton ~ Bean Bari Deshon ~