@Test public void prototypeCreationIsFastEnough() { if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { // Skip this test: Trace logging blows the time limit. return; } GenericApplicationContext ac = new GenericApplicationContext(); RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class); rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); rbd.getConstructorArgumentValues().addGenericArgumentValue("#{systemProperties.name}"); rbd.getPropertyValues().add("country", "#{systemProperties.country}"); ac.registerBeanDefinition("test", rbd); ac.refresh(); StopWatch sw = new StopWatch(); sw.start("prototype"); System.getProperties().put("name", "juergen"); System.getProperties().put("country", "UK"); try { for (int i = 0; i < 100000; i++) { TestBean tb = (TestBean) ac.getBean("test"); assertEquals("juergen", tb.getName()); assertEquals("UK", tb.getCountry()); } sw.stop(); } finally { System.getProperties().remove("country"); System.getProperties().remove("name"); } assertTrue( "Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 6000); }
@Test public void prototypeCreationReevaluatesExpressions() { GenericApplicationContext ac = new GenericApplicationContext(); AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class); rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); rbd.getPropertyValues().add("country", "#{systemProperties.country}"); rbd.getPropertyValues().add("country2", new TypedStringValue("#{systemProperties.country}")); ac.registerBeanDefinition("test", rbd); ac.refresh(); try { System.getProperties().put("name", "juergen1"); System.getProperties().put("country", "UK1"); PrototypeTestBean tb = (PrototypeTestBean) ac.getBean("test"); assertEquals("juergen1", tb.getName()); assertEquals("UK1", tb.getCountry()); assertEquals("UK1", tb.getCountry2()); System.getProperties().put("name", "juergen2"); System.getProperties().put("country", "UK2"); tb = (PrototypeTestBean) ac.getBean("test"); assertEquals("juergen2", tb.getName()); assertEquals("UK2", tb.getCountry()); assertEquals("UK2", tb.getCountry2()); } finally { System.getProperties().remove("name"); System.getProperties().remove("country"); } }
@Test public void testResourceInjectionWithResolvableDependencyType() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor(); bpp.setBeanFactory(bf); bf.addBeanPostProcessor(bpp); RootBeanDefinition abd = new RootBeanDefinition(ExtendedResourceInjectionBean.class); abd.setScope(BeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("annotatedBean", abd); RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class); tbd.setScope(BeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("testBean4", tbd); bf.registerResolvableDependency(BeanFactory.class, bf); bf.registerResolvableDependency(INestedTestBean.class, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return new NestedTestBean(); } }); PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); Properties props = new Properties(); props.setProperty("tb", "testBean4"); ppc.setProperties(props); ppc.postProcessBeanFactory(bf); ExtendedResourceInjectionBean bean = (ExtendedResourceInjectionBean) bf.getBean("annotatedBean"); INestedTestBean tb = bean.getTestBean6(); assertNotNull(tb); ExtendedResourceInjectionBean anotherBean = (ExtendedResourceInjectionBean) bf.getBean("annotatedBean"); assertNotSame(anotherBean, bean); assertNotSame(anotherBean.getTestBean6(), tb); String[] depBeans = bf.getDependenciesForBean("annotatedBean"); assertEquals(1, depBeans.length); assertEquals("testBean4", depBeans[0]); }
@Test public void testResourceInjectionWithPrototypes() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor(); bpp.setResourceFactory(bf); bf.addBeanPostProcessor(bpp); RootBeanDefinition abd = new RootBeanDefinition(ResourceInjectionBean.class); abd.setScope(BeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("annotatedBean", abd); RootBeanDefinition tbd1 = new RootBeanDefinition(TestBean.class); tbd1.setScope(BeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("testBean", tbd1); RootBeanDefinition tbd2 = new RootBeanDefinition(TestBean.class); tbd2.setScope(BeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("testBean2", tbd2); ResourceInjectionBean bean = (ResourceInjectionBean) bf.getBean("annotatedBean"); assertTrue(bean.initCalled); assertTrue(bean.init2Called); assertTrue(bean.init3Called); TestBean tb = bean.getTestBean(); TestBean tb2 = bean.getTestBean2(); assertNotNull(tb); assertNotNull(tb2); ResourceInjectionBean anotherBean = (ResourceInjectionBean) bf.getBean("annotatedBean"); assertNotSame(anotherBean, bean); assertNotSame(anotherBean.getTestBean(), tb); assertNotSame(anotherBean.getTestBean2(), tb2); bf.destroyBean("annotatedBean", bean); assertTrue(bean.destroyCalled); assertTrue(bean.destroy2Called); assertTrue(bean.destroy3Called); }
public void testSerializability() throws Exception { MutablePropertyValues tsPvs = new MutablePropertyValues(); tsPvs.addPropertyValue("targetBeanName", "person"); RootBeanDefinition tsBd = new RootBeanDefinition(TestTargetSource.class, tsPvs); MutablePropertyValues pvs = new MutablePropertyValues(); RootBeanDefinition bd = new RootBeanDefinition(SerializablePerson.class, pvs); bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.registerBeanDefinition("ts", tsBd); bf.registerBeanDefinition("person", bd); TestTargetSource cpts = (TestTargetSource) bf.getBean("ts"); TargetSource serialized = (TargetSource) SerializationTestUtils.serializeAndDeserialize(cpts); assertTrue( "Changed to SingletonTargetSource on deserialization", serialized instanceof SingletonTargetSource); SingletonTargetSource sts = (SingletonTargetSource) serialized; assertNotNull(sts.getTarget()); }
@Override public Object buildBean(String beanName, Map<String, Object> extraContext) throws Exception { LOG.debug("Building bean for name {}", beanName); if (!skipBeanNames.contains(beanName)) { ApplicationContext anAppContext = getApplicationContext(extraContext); try { LOG.debug( "Trying the application context... appContext = {},\n bean name = {}", anAppContext, beanName); return anAppContext.getBean(beanName); } catch (NoSuchBeanDefinitionException e) { LOG.debug( "Did not find bean definition for bean named {}, creating a new one...", beanName); if (autoWiringFactory instanceof BeanDefinitionRegistry) { try { Class clazz = Class.forName(beanName); BeanDefinitionRegistry registry = (BeanDefinitionRegistry) autoWiringFactory; RootBeanDefinition def = new RootBeanDefinition(clazz, autowireStrategy, true); def.setScope(BeanDefinition.SCOPE_SINGLETON); LOG.debug("Registering a new bean definition for class {}", beanName); registry.registerBeanDefinition(beanName, def); try { return anAppContext.getBean(beanName); } catch (NoSuchBeanDefinitionException e2) { LOG.warn("Could not register new bean definition for bean {}", beanName); skipBeanNames.add(beanName); } } catch (ClassNotFoundException e1) { skipBeanNames.add(beanName); } } } } LOG.debug("Returning autowired instance created by default ObjectFactory"); return autoWireBean(super.buildBean(beanName, extraContext), autoWiringFactory); }
@Test public void nonSingletonListenerInApplicationContext() { StaticApplicationContext context = new StaticApplicationContext(); RootBeanDefinition listener = new RootBeanDefinition(MyNonSingletonListener.class); listener.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); context.registerBeanDefinition("listener", listener); context.refresh(); MyEvent event1 = new MyEvent(context); context.publishEvent(event1); MyOtherEvent event2 = new MyOtherEvent(context); context.publishEvent(event2); MyEvent event3 = new MyEvent(context); context.publishEvent(event3); MyOtherEvent event4 = new MyOtherEvent(context); context.publishEvent(event4); assertTrue(MyNonSingletonListener.seenEvents.contains(event1)); assertTrue(MyNonSingletonListener.seenEvents.contains(event2)); assertTrue(MyNonSingletonListener.seenEvents.contains(event3)); assertTrue(MyNonSingletonListener.seenEvents.contains(event4)); MyNonSingletonListener.seenEvents.clear(); context.close(); }
/** * Read a particular {@link ConfigurationClassMethod}, registering bean definitions with the * BeanDefinitionRegistry based on its contents. */ private void loadBeanDefinitionsForBeanMethod(ConfigurationClassMethod beanMethod) { ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); RootBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass); beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setUniqueFactoryMethodName(metadata.getMethodName()); beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAttribute( RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); // consider name and any aliases Map<String, Object> beanAttributes = metadata.getAnnotationAttributes(Bean.class.getName()); List<String> names = new ArrayList<String>(Arrays.asList((String[]) beanAttributes.get("name"))); String beanName = (names.size() > 0 ? names.remove(0) : beanMethod.getMetadata().getMethodName()); for (String alias : names) { this.registry.registerAlias(beanName, alias); } // has this already been overridden (e.g. via XML)? if (this.registry.containsBeanDefinition(beanName)) { BeanDefinition existingBeanDef = registry.getBeanDefinition(beanName); // is the existing bean definition one that was created from a configuration class? if (!(existingBeanDef instanceof ConfigurationClassBeanDefinition)) { // no -> then it's an external override, probably XML // overriding is legal, return immediately if (logger.isDebugEnabled()) { logger.debug( String.format( "Skipping loading bean definition for %s: a definition for bean " + "'%s' already exists. This is likely due to an override in XML.", beanMethod, beanName)); } return; } } if (metadata.isAnnotated(Primary.class.getName())) { beanDef.setPrimary(true); } // is this bean to be instantiated lazily? if (metadata.isAnnotated(Lazy.class.getName())) { beanDef.setLazyInit( (Boolean) metadata.getAnnotationAttributes(Lazy.class.getName()).get("value")); } else if (configClass.getMetadata().isAnnotated(Lazy.class.getName())) { beanDef.setLazyInit( (Boolean) configClass.getMetadata().getAnnotationAttributes(Lazy.class.getName()).get("value")); } if (metadata.isAnnotated(DependsOn.class.getName())) { String[] dependsOn = (String[]) metadata.getAnnotationAttributes(DependsOn.class.getName()).get("value"); if (dependsOn.length > 0) { beanDef.setDependsOn(dependsOn); } } Autowire autowire = (Autowire) beanAttributes.get("autowire"); if (autowire.isAutowire()) { beanDef.setAutowireMode(autowire.value()); } String initMethodName = (String) beanAttributes.get("initMethod"); if (StringUtils.hasText(initMethodName)) { beanDef.setInitMethodName(initMethodName); } String destroyMethodName = (String) beanAttributes.get("destroyMethod"); if (StringUtils.hasText(destroyMethodName)) { beanDef.setDestroyMethodName(destroyMethodName); } // consider scoping ScopedProxyMode proxyMode = ScopedProxyMode.NO; Map<String, Object> scopeAttributes = metadata.getAnnotationAttributes(Scope.class.getName()); if (scopeAttributes != null) { beanDef.setScope((String) scopeAttributes.get("value")); proxyMode = (ScopedProxyMode) scopeAttributes.get("proxyMode"); if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = ScopedProxyMode.NO; } } // replace the original bean definition with the target one, if necessary BeanDefinition beanDefToRegister = beanDef; if (proxyMode != ScopedProxyMode.NO) { BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); beanDefToRegister = proxyDef.getBeanDefinition(); } if (logger.isDebugEnabled()) { logger.debug( String.format( "Registering bean definition for @Bean method %s.%s()", configClass.getMetadata().getClassName(), beanName)); } registry.registerBeanDefinition(beanName, beanDefToRegister); }