[Java Spring MVC] I want to use DI in my own class

2018-11-05 Addendum

In PHP's Laravel, getting an object globally via DI resolution from any class didn't cause any problems (which didn't happen to my knowledge), but in Spring it involves an annoying element of context, so Laravel It seems that it is not possible to have a DI solution with Hoi Hoi with a glue like this.

As usual, this is a story in a state where Spring Boot is not used, so it may not be the case when Spring Boot is introduced, but at this stage we have not been able to investigate that much.


Assigned to a Web system project using Java's Spring MVC. Spring Boot is not used because it seems to be a system made a little while ago. I'm still new to Java web systems, so it's very difficult to do.

Spring MVC seems to use annotations like "@Inject" for DI. Recently, I learned a little about domain-driven development, so I tried to make a simple domain object related to the repair part by thinking about making a domain object (an object that bears an easy-to-understand unit of work).

However, I learned that DI using annotations cannot be used in a class that does not follow the rules of Spring MVC, that is, in a self-made class. As a result of searching for an alternative method, I found it as it is, so I will briefly summarize it here.

Overview

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;


(Omission)

    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
    HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
    ServletContext servletContext = httpServletRequest.getServletContext();
    WebApplicationContext webApplicationContext =
        WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);

    //Get instance by bean definition name
    //Since it returns as Object type, cast it to the desired class
Target type variable name= (Cast to the desired mold) webApplicationContext.getBean("Bean definition name");

    //Get bean definition name list getBean()You can check the character string that can be used as an argument of.
    String[] beanDefinitionNames = webApplicationContext.getBeanDefinitionNames();

ApplicationContext.getBean ("Bean definition name")

Get ServletContext

How to find out the bean definition name

Sample class

package Specify the package name;

import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 *Domain object
 *DI (DependencyInjectionSolver) solver
 *In a self-made class not managed by Spring@DI using annotations such as Inject does not work, so
 *Get the DI resolved instance via this class.
 *
 *When testing the process that uses this class, JUnit's Test class says "@Annotate "WebAppConfiguration".
 */
public class DependencyInjectionSolver {
  private static final Logger logger = LoggerFactory.getLogger(DependencyInjectionSolver.class);

  /**
   *ApplicationContext for getting beans through this instance
   */
  private WebApplicationContext webApplicationContext;

  public DependencyInjectionSolver() {
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
    HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
    ServletContext servletContext = httpServletRequest.getServletContext();
    this.webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
  }

  /**
   *Receive the bean definition name and get the DI resolved instance.
   *Since it returns as Object type, cast it on the acquisition side.
   *
   * @param string Bean definition name
   * @return Object
   */
  public Object getBeanByBeanName(String beanName) {
    return this.webApplicationContext.getBean(beanName);
  }

  /**
   *Get a list of defined Bean definition names.
   *GetBeanByBeanName for the names in this list()It can be used as an argument of.
   *
   * @return List<string>List of bean definition names
   */
  public List<String> gettableBeanNames() {
    String[] beanDefinitionNames = this.webApplicationContext.getBeanDefinitionNames();
    return Arrays.asList(beanDefinitionNames);
  }
}

User side

DependencyInjectionSolver diSolver = new DependencyInjectionSolver();
Variable name such as interface name= (Interface name etc.) diSolver.getBeanByBeanName("Bean definition name");

Recommended Posts

[Java Spring MVC] I want to use DI in my own class
I want to use ES2015 in Java too! → (´ ・ ω ・ `)
I want to use @Autowired in Servlet
[java] What I did when comparing Lists in my own class
I want to send an email in Java.
I want to use arrow notation in Ruby
I want to use java8 forEach with index
rsync4j --I want to touch rsync in Java.
My memorandum that I want to make ValidationMessages.properties UTF8 in Spring Boot
I want to use Clojure's convenient functions in Kotlin
I want to do something like "cls" in Java
I want to use fish shell in Laradock too! !!
How to use java class
I want to use PowerMock in a class that combines parameterized tests and ordinary tests
How to call and use API in Java (Spring Boot)
Even in Java, I want to output true with a == 1 && a == 2 && a == 3
I tried to summarize object orientation in my own way.
I want to simplify the conditional if-else statement in Java
How to use Lombok in Spring
I want to use FormObject well
I was trapped when I generated my own class equals and hashCode in Java using IDE
[Java] How to use LinkedHashMap class
How to use class methods [Java]
How to use classes in Java?
[Java] How to use Math class
I just want to write Java using Eclipse on my Mac
I tried setting Java beginners to use shortcut keys in eclipse
[Java] I want to perform distinct with the key in the object
[Spring Boot] I want to add my own property file and get the value with env.getProperty ().
Multilingual Locale in Java How to use Locale
[Java] How to use the HashMap class
I want to use DBViewer with Eclipse 2018-12! !!
[Processing × Java] How to use the class
How to use Java Scanner class (Note)
I want to stop Java updates altogether
[Java] How to use the Calendar class
[* Java *] I participated in JJUG CCC 2019 Spring
I want to display images with REST Controller of Java and Spring!
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (PowerMockito edition)
(Limited to Java 7 or later) I want you to compare objects in Objects.equals
I want to get the IP address when connecting to Wi-Fi in Java
I want to ForEach an array with a Lambda expression in Java
"Teacher, I want to implement a login function in Spring" ① Hello World
Which class should I use to get the date and time in my Rails app (Time, DateTime, TimeWithZone)
[Java] How to use FileReader class and BufferedReader class
Java method call from RPG (method call in own class)
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (Javassist second decoction)
I tried to implement deep learning in Java
How to get Class from Element in Java
I want to pass APP_HOME to logback in Gradle
I want you to use Scala as Better Java for the time being
[Xcode] I want to manage images in folders
[JAVA] [Spring] [MyBatis] Use IN () with SQL Builder
I want to write quickly from java to sqlite
I tried to create Alexa skill in Java
Let's create a TODO application in Java 2 I want to create a template with Spring Initializr and make a Hello world
[Java] Spring DI ③
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (black magic edition)
I want to get the value in Ruby
[Java] How to use Calendar class and Date class
I want to get the information of the class that inherits the UserDetails class of the user who is logged in with Spring Boot.