1.Bean Life-Cycle Management
<bean id="simpleBean1" class="com.apress.prospring3.ch5.lifecycle.SimpleBean" init-method="init" />
<bean id="destructiveBean" class="com.apress.prospring3.ch5.lifecycle.DestructiveBean" destroy-method="destroy"/>
public class SimpleBeanWithInterface implements InitializingBean{ private static final String DEFAULT_NAME = "Luke Skywalker"; private String name = null; private int age = Integer.MIN_VALUE; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void myInit() { System.out.println("My Init"); } public void afterPropertiesSet() throws Exception { System.out.println("Initializing bean"); if (name == null) { System.out.println("Using default name"); name = DEFAULT_NAME; }
public class DestructiveBeanWithInterface implements InitializingBean, DisposableBean{ private InputStream is = null; public String filePath = null; public void afterPropertiesSet() throws Exception { System.out.println("Initializing Bean"); if (filePath == null) { throw new IllegalArgumentException( "You must specify the filePath property of " + DestructiveBean.class); } is = new FileInputStream(filePath); } public void destroy() { System.out.println("Destroying Bean"); if (is != null) { try { is.close(); is = null; } catch (IOException ex) { System.err.println("WARN: An IOException occured" + " trying to close the InputStream"); } } } public void setFilePath(String filePath) { this.filePath = filePath; }
public class SimpleBeanWithJSR250 { // Codes omitted @PostConstruct public void init() throws Exception { // Rest of codes omitted } }
public class DestructiveBeanWithJSR250 { private InputStream is = null; public String filePath = null; @PostConstruct public void afterPropertiesSet() throws Exception { System.out.println("Initializing Bean"); if (filePath == null) { throw new IllegalArgumentException( "You must specify the filePath property of " + DestructiveBean.class); } is = new FileInputStream(filePath); } @PreDestroy public void destroy() { System.out.println("Destroying Bean"); if (is != null) { try { is.close(); is = null; } catch (IOException ex) { System.err.println("WARN: An IOException occured" + " trying to close the InputStream"); } } } public void setFilePath(String filePath) { this.filePath = filePath; }
2.Making Your Beans “Spring Aware”
public class ShutdownHookBean implements ApplicationContextAware { private ApplicationContext ctx; public void setApplicationContext(ApplicationContext ctx) throws BeansException { if (ctx instanceof GenericApplicationContext) { ((GenericApplicationContext) ctx).registerShutdownHook(); } } }
<bean id="destructiveBean" class="com.apress.prospring3.ch5.lifecycle.DestructiveBeanWithInterface"> <property name="filePath"> <value>d:/temp/test.txt</value> </property> </bean> <bean id="shutdownHook" class="com.apress.prospring3.ch5.interaction.ShutdownHookBean"/>
3.Using ApplicationContext and MessageSource
public static void main(String[] args) { GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); ctx.load("classpath:appContext/messageSource.xml"); ctx.refresh(); Locale english = Locale.ENGLISH; Locale czech = new Locale("cs", "CZ"); System.out.println(ctx.getMessage("msg", null, english)); System.out.println(ctx.getMessage("msg", null, czech)); System.out.println(ctx.getMessage("nameMsg", new Object[] { "Clarence", "Ho" }, english)); }
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>buttons</value> <value>labels</value> </list> </property> </bean>
4.Using Application Events
public class MessageEvent extends ApplicationEvent { private String msg; public MessageEvent(Object source, String msg) { super(source); this.msg = msg; } public String getMessage() { return msg; } }
public class MessageEventListener implements ApplicationListener<MessageEvent> { public void onApplicationEvent(MessageEvent event) { MessageEvent msgEvt = (MessageEvent) event; System.out.println("Received: " + msgEvt.getMessage()); } }
public class Publisher implements ApplicationContextAware { private ApplicationContext ctx; public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:events/events.xml"); Publisher pub = (Publisher) ctx.getBean("publisher"); pub.publish("Hello World!"); pub.publish("The quick brown fox jumped over the lazy dog"); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.ctx = applicationContext; } public void publish(String message) { ctx.publishEvent(new MessageEvent(this, message)); } }
<bean id="publisher" class="com.apress.prospring3.ch5.event.Publisher"/> <bean id="messageEventListener" class="com.apress.prospring3.ch5.event.MessageEventListener"/>
5.Accessing Resources
public static void main(String[] args) throws Exception{ ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:events/events.xml"); Resource res1 = ctx.getResource("file:///d:/temp/test.txt"); displayInfo(res1); Resource res2 = ctx.getResource("classpath:test.txt"); displayInfo(res2); Resource res3 = ctx.getResource("http://www.google.co.uk"); displayInfo(res3); } private static void displayInfo(Resource res) throws Exception{ System.out.println(res.getClass()); System.out.println(res.getURL().getContent()); System.out.println(""); //getFile(), getInputStream(), or getURL() } 6. Java Configuration
@Configuration public class AppConfig { // XML: // <bean id="messageProvider" class="com.apress.prospring3.ch5.javaconfig.ConfigurableMessageProvider"/> @Bean public MessageProvider messageProvider() { return new ConfigurableMessageProvider(); } // XML: // <bean id="messageRenderer" class="com.apress.prospring3.ch5.javaconfig.StandardOutMessageRenderer" // p:messageProvider-ref="messageProvider"/> @Bean public MessageRenderer messageRenderer() { MessageRenderer renderer = new StandardOutMessageRenderer(); // Setter injection renderer.setMessageProvider(messageProvider()); return renderer; }
@Configuration @Import(OtherConfig.class) // XML: <import resource="classpath:events/events.xml") @ImportResource(value="classpath:events/events.xml") // XML: <context:property-placeholder location="classpath:message.properties"/> @PropertySource(value="classpath:message.properties") // XML: <context:component-scan base-package="com.apress.prospring3.ch5.context"/> @ComponentScan(basePackages={"com.apress.prospring3.ch5.context"}) @EnableTransactionManagement public class AppConfig { @Autowired Environment env; // XML: // <bean id="messageProvider" class="com.apress.prospring3.ch5.javaconfig.ConfigurableMessageProvider"/> @Bean @Lazy(value=true) //XML <bean .... lazy-init="true"/> public MessageProvider messageProvider() { // Constructor injection return new ConfigurableMessageProvider(env.getProperty("message")); } // XML: // <bean id="messageRenderer" class="com.apress.prospring3.ch5.javaconfig.StandardOutMessageRenderer" // p:messageProvider-ref="messageProvider"/> @Bean(name="messageRenderer") @Scope(value="prototype") // XML: <bean ... scope="prototype"/> @DependsOn(value="messageProvider") // XML: <bean ... depends-on="messageProvider"/> public MessageRenderer messageRenderer() { MessageRenderer renderer = new StandardOutMessageRenderer(); // Setter injection renderer.setMessageProvider(messageProvider()); return renderer; } }
7.ConfigurableEnvironment env = ctx.getEnvironment();
MutablePropertySources propertySources = env.getPropertySources();
8.JSR-330
@Named("messageRenderer") @Singleton public class StandardOutMessageRenderer implements MessageRenderer { @Inject @Named("messageProvider") private MessageProvider messageProvider = null; public void render() { if (messageProvider == null) { throw new RuntimeException( "You must set the property messageProvider of class:" + StandardOutMessageRenderer.class.getName()); } System.out.println(messageProvider.getMessage()); } public void setMessageProvider(MessageProvider provider) { this.messageProvider = provider; } public MessageProvider getMessageProvider() { return this.messageProvider; } }