Inject Spring Bean vào các class không phải là @Component

Inject Spring Bean vào các class không phải là @Component.

(Xem thêm: Code ví dụ Spring Boot Inject bean ApplicationContextAware)

Các bean quản lý bởi Spring

Trong Spring, các class (bean) được quản lý bởi Spring là các class được đánh dấu annotation (@Component, @Service, @Repository) hoặc được cấu hình trong file .xml với thẻ <bean>

Và khi muốn sử dụng các class này ta sẽ thực hiện Inject / AutoWiring với annotation @Inject / @Autowired.

Không sử dụng từ khóa new nhé, vì các đối tượng khởi tạo bằng từ khóa new sẽ không được quản lý bởi Spring và có thể gây ra một số lỗi.

Ví dụ:

@Service
public class UserService {
  
  @Autowired
  private UserDAO userDAO;
}

@Repository
public class UserDAO {

  public void save() {
    System.out.println("-------- Save User --------");
  }
}

Cả UserServiceUserDAO đều là 2 Spring Bean. Khi bạn khởi tạo UserService với từ khóa new sẽ xảy ra lỗi bởi vì khi đó UserService không còn được quản lý bởi Spring nên từ khóa @Autowired bên trong nó cũng không còn tác dụng.

Để sử dụng UserService ta cần inject nó giống như 1 bean của Spring vào class sử dụng bằng annotation @Autowired

Tuy nhiên, trong nhiều trường hợp, class sử dụng UserService không được quản lý bởi Spring nên ta không thể sử dụng @Autowired. Trong bài này chúng ta sẽ giải quyết vấn đề đó.

Inject Spring Bean vào các class không được quản lý bởi Spring

Để lấy được spring bean từ các class không được quản lý bởi Spring, ta implements interface ApplicationContextAware

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public class BeanUtils implements ApplicationContextAware {
  private static ApplicationContext context;

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    context = applicationContext;
  }

  public static <T> T getBean(Class<T> beanClass) {
    return context.getBean(beanClass);
  }
}

Khi implements interface ApplicationContextAware ta có thể truy cập các bean, các file resource.

Khi muốn sử dụng một bean bất kỳ ta gọi BeanUtils.getBean(class_name.class);

Ví dụ

public class MainApp {
  
  public void save() {
    UserDAO userDAO = BeanUtils.getBean(UserDAO.class);
    userDAO.save();
  }
}

 

Okay. Done!

(Xem thêm: Code ví dụ Spring Boot Inject bean ApplicationContextAware)

References:

https://stackoverflow.com/…/injecting-beans-into-a-class-outside-the-spring-managed-context

stackjava.com