Dynamically creating Spring Beans at runtime

The translation has been prepared especially for future students of the course "Developer on Spring Framework" .


This article on dynamic bin creation has become the most popular on my blog in five years (over 9,300 views). It's time to update it. I also added an example on Github .

Spring Bean dynamics on Github
Spring Bean Github

: " Spring Bean , ". , . properties-.

1. , , :

package your.package;

@Retention(RetentionPolicy.RUNTIME)
public @interface InjectDynamicObject {
}

2. , :

@Service
public class CustomerServiceImpl {
    private Customer dynamicCustomerWithAspect;
    
    @InjectDynamicObject
    public Customer getDynamicCustomerWithAspect() {
        return this.dynamicCustomerWithAspect;
    }
}

3. Pointcut Advise, , 2:

@Component
@Aspect
public class DynamicObjectAspect {
    // This comes from the property file
    @Value("${dynamic.object.name}")
    private String object;
    @Autowired
    private ApplicationContext applicationContext;
    
    @Pointcut("execution(@com.lofi.springbean.dynamic.
        InjectDynamicObject * *(..))")
    public void beanAnnotatedWithInjectDynamicObject() {
    }
    @Around("beanAnnotatedWithInjectDynamicObject()")
    public Object adviceBeanAnnotatedWithInjectDynamicObject(
        ProceedingJoinPoint pjp) throws Throwable {   
        pjp.proceed();
        
        // Create the bean or object depends on the property file  
        Object createdObject = applicationContext.getBean(object);
        return createdObject;
    }
}

4. , @InjectDynamicObject. properties-. Customer: CustomerOneImpl CustomerTwoImpl:

@Component("customerOne")
public class CustomerOneImpl implements Customer {
    @Override
    public String getName() {
        return "Customer One";
    }
}

application.properties
dynamic.object.name=customerOne

5. :

@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerServiceImplTest {
    @Autowired
    private CustomerServiceImpl customerService;
    @Test
    public void testGetDynamicCustomerWithAspect() {
        // Dynamic object creation
        logger.info("Dynamic Customer with Aspect: " +
            customerService.getDynamicCustomerWithAspect()
            .getName());
}

, , . AspectJ, Spring. Map . eXTra Client. PluginsLocatorManager. Spring Map (String) .

"… Map , String. Map , β€” ".

. Spring.

@Service
public class CustomerServiceImpl {
    
    // We inject the customer implementations into a Map
    @Autowired
    private Map<String, Customer> dynamicCustomerWithMap;
    
    // This comes from the property file as a key for the Map
    @Value("${dynamic.object.name}")
    private String object;
    public Customer getDynamicCustomerWithMap() {
        return this.dynamicCustomerWithMap.get(object);
    }
}

" Spring Framework" .




All Articles