@Service @Scope("prototype") public class ServiceA { private Customer customer; private ReloadType reloadType; private ServiceB serviceB; @Autowired private ApplicationContext context; public ServiceA(final Customer customer, final ReloadType reloadType) { this.customer = customer; this.reloadType = reloadType; } @PostConstruct public void init(){ serviceB = (ServiceB) context.getBean("serviceB",customer, reloadType); } public void doSomethingInteresting(){ doSomthingWithCustomer(customer,reloadType); serviceB.doSomethingBoring(); } private void doSomthingWithCustomer(final Customer customer, final ReloadType reloadType) { } }
@Service @Scope("prototype") public class ServiceB { private Customer customer; private ReloadType reloadType; public ServiceB(final Customer customer, final ReloadType reloadType) { this.customer = customer; this.reloadType = reloadType; } public void doSomethingBoring(){ } }
//... ServiceA serviceA = (ServiceA) context.getBean("serviceA",customer, ReloadType.FullReaload); serviceA.doSomethingInteresting(); //...
.. <bean id="customerScope" class="com.scope.CustomerScope"/> <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="customer" value-ref="customerScope"/> </map> </property> </bean> ...
public class CustomerScope implements Scope { @Override public Object get(String name, ObjectFactory<?> objectFactory) { CustomerContext context = resolve(); Object result = context.getBean(name); if (result == null) { result = objectFactory.getObject(); ICustomerScopeBean syncScopedBean = (ICustomerScopeBean) result; syncScopedBean.setContext(context); Object oldBean = context.setBean(name, result); if (oldBean != null) { result = oldBean; } } return result; } @Override public Object remove(String name) { CustomerContext context = resolve(); return context.removeBean(name); } protected CustomerContext resolve() { return CustomerContextThreadLocal.getCustomerContext(); } @Override public void registerDestructionCallback(String name, Runnable callback) { } @Override public Object resolveContextualObject(String key) { return null; } @Override public String getConversationId() { return resolve().toString(); } }
public class CustomerContextThreadLocal { private static ThreadLocal<CustomerContext> customerContext = new ThreadLocal<>(); public static CustomerContext getCustomerContext() { return customerContext.get(); } public static void setSyncContext(CustomerContext context) { customerContext.set(context); } public static void clear() { customerContext.remove(); } private CustomerContextThreadLocal() { } public static void setSyncContext(Customer customer, ReloadType reloadType) { setSyncContext(new CustomerContext(customer, reloadType)); }
public interface ICustomerScopeBean { void setContext(CustomerContext context); } public class AbstractCustomerScopeBean implements ICustomerScopeBean { protected Customer customer; protected ReloadType reloadType; @Override public void setContext(final CustomerContext context) { customer = context.getCustomer(); reloadType = context.getReloadType(); } }
@Service @Scope("customer") public class ServiceA extends AbstractCustomerScopeBean { @Autowired private ServiceB serviceB; public void doSomethingInteresting() { doSomthingWithCustomer(customer, reloadType); serviceB.doSomethingBoring(); } private void doSomthingWithCustomer(final Customer customer, final ReloadType reloadType) { } } @Service @Scope("customer") public class ServiceB extends AbstractCustomerScopeBean { public void doSomethingBoring(){ } } //.... CustomerContextThreadLocal.setSyncContext(customer, ReloadType.FullReaload); ServiceA serviceA = context.getBean(ServiceA.class); serviceA.doSomethingInteresting(); //.....
@ContextConfiguration(locations = {"classpath:beans.xml"}, loader = GenericXmlContextLoader.class) @RunWith(SpringJUnit4ClassRunner.class) public class CustomerBeanScopetest { @Autowired private AbstractApplicationContext context; @Test public void testScopeBeans() throws ClassNotFoundException { ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); for (String beanDef : beanDefinitionNames) { BeanDefinition def = beanFactory.getBeanDefinition(beanDef); String scope = def.getScope(); String beanClassName = def.getBeanClassName(); if (beanClassName == null) continue; Class<?> aClass = Class.forName(beanClassName); if (ICustomerScopeBean.class.isAssignableFrom(aClass)) assertTrue(beanClassName + " should have scope 'customer'", scope.equals("customer")); if (scope.equals("customer")) assertTrue(beanClassName + " should implement 'ICustomerScopeBean'", ICustomerScopeBean.class.isAssignableFrom(aClass)); } } }
Source: https://habr.com/ru/post/225397/
All Articles