3 Spring IoC GoF Design Patterns: Elements of Reusable Object-Oriented Software Programming to an Interface not an Implementation Java Java Java GoF Service Locator IoC IoC Spring IoC 3.1 IoC IoC IoC Dependency Injection 1 IoC Hollywood Don t call me, I ll call you 2 IoC IoC IoC IoC IoC IoC 1 IoC IoC IoC JNDI IoC 1 Robert C. Martin The Dependency Inversion Principle http://www.objectmentor.com/resources/articles/dip.pdf 2 Rod Johnson TheServerSide.com Introducing the Spring Framework http://www.theserverside.com/articles/article.tss?l=springframework
Spring IoC IoC API IoC IoC Spring PicoContainer Apache HiveMind Spring IoC Java/J2EE Spring AOP Spring MVC Framework O/R Mapping DAO Spring Acegi Open Source Spring IoC 3.2 Spring IoC Spring IoC IoC Spring IoC Spring IoC Spring IoC BeanFactory org.springframework.beans.factory XML JavaBean Java Applet ApplicationContext org.springframework.context ApplicationContext BeanFactory BeanFactory Spring IoC J2EE Spring BeanFactory ApplicationContext 3.2.1 BeanFactory Spring BeanFactory Spring Applet Swing/SWT BeanFactory EJB Spring BeanFactory BeanFactory Spring IoC BeanFactory BeanFactory JavaBean BeanFactory IoC IoC BeanFactory Spring JavaBean 30
3 Spring IoC Spring org.springframework.beans.factory.beanfactory XmlBeanFactory 3-1 BeanFactory 3-1 BeanFactory BeanFactory XmlBeanFactory example4 appcontext.xml HelloWorldClient appcontext.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean name="filehelloworld" class="com.openv.spring.helloworld"> <constructor-arg> <ref bean="filehello"/> </constructor-arg> <bean name="filehello" class="com.openv.spring.filehellostr"> <constructor-arg> <value>helloworld.properties</value> </constructor-arg> </beans> Spring appcontext.xml spring-beans.dtd spring-beans.dtd JavaBean BeanFactory Spring BeanFactory Web B spring-beans.dtd 31
Spring example4 3-2 UML 3-2 example4 UML HelloWorldClient.java 1 public class HelloWorldClient { protected static final Log log = LogFactory.getLog(HelloWorldClient.class); public HelloWorldClient(){ Resource resource = new ClassPathResource("appcontext.xml"); BeanFactory factory = new XmlBeanFactory(resource); HelloWorld hw = (HelloWorld)factory.getBean("fileHelloWorld"); log.info(hw.getcontent()); public static void main(string[] args) { new HelloWorldClient(); Spring appcontext.xml XmlBeanFactory appcontext.xml Spring org.springframework.core.io appcontext.xml try { InputStream ins = new FileInputStream("src/appcontext.xml"); BeanFactory factory = new XmlBeanFactory(ins); HelloWorld hw = (HelloWorld) factory.getbean("filehelloworld"); log.info(hw.getcontent()); catch (FileNotFoundException ex) { log.error(" appcontext.xml ", ex); ApplicationContext appcontext.xml ClassPathXmlApplicationContext appcontext = new ClassPathXmlApplicationContext( new String[] { "appcontext.xml" ); BeanFactory factory = (BeanFactory) appcontext; HelloWorld hw = (HelloWorld) factory.getbean("filehelloworld"); log.info(hw.getcontent()); BeanFactory Spring 32
3 Spring IoC Spring Web J2EE Web Spring ApplicationContext appcontext.xml JavaBean BeanFactory getbean JavaBean JavaBean example4 BeanFactory 1 Bean BeanFactory Bean IoC BeanFactory JavaBean IoC Spring JavaBean Spring BeanDefinition Bean IoC JavaBean 4 JavaBean JavaBean IoC JavaBean Spring JavaBean IoC JavaBean 3-3 JavaBean 3-3 BeanFactory Bean 3 3 Spring Live 33
Spring Spring DTD B spring-beans.dtd 2 Bean JavaBean 3-3 JavaBean JavaBean <bean name="filehelloworld" class="com.openv.spring.helloworld"> HelloWorld JavaBean <bean name="filehelloworld" class="com.openv.spring.helloworld" factory-method= createhelloworldinstance > HelloWorld createhelloworldinstance <bean name= helloworldfactory class= com.openv.spring.helloworldfactory /> <bean name="filehelloworld" factory-bean= helloworldfactory factory-method= createhelloworldinstance > filehelloworld JavaBean HelloWorldFactory createhelloworldinstance Spring JavaBean example4 Spring <bean name="filehelloworld" class="com.openv.spring.helloworld"> <constructor-arg> <ref bean="filehello"/> </constructor-arg> <ref> Spring filehello JavaBean Spring DTD <ref> bean Spring XML BeanFactory ApplicationContext JavaBean local Spring XML JavaBean Spring XML Spring IDE JavaBean local XML parent JavaBean 34
3 Spring IoC 3 JavaBean 3-3 JavaBean <bean> autowire Spring autowire Spring JavaBean JavaBean B <bean> dependency-check Spring JavaBean B setter JavaBean Java primitive Spring JavaBean null <bean id="example11service" class="org.springframework.transaction.interceptor.transactionproxyfa ctorybean"> <property name="transactionmanager"> <ref local="transactionmanager"/> <property name="target"> <ref local="example11servicetarget"/> <property name="transactionattributes"> <props> <prop key="get*"> PROPAGATION_REQUIRED,readOnly </prop> <prop key="set*"> PROPAGATION_REQUIRED </prop> </props> Spring TransactionProxyFactoryBean transactionmanager target transactionattributes transactionmanager <ref> transactionmanager POJO Spring transactionmanager <bean id="transactionmanager" class="org.springframework.transaction.jta.jtatransactionmanager"> <property name="usertransactionname"> <value>java:comp/usertransaction</value> 35
Spring <ref> JavaBean <property name="transactionmanager"> <bean class="org.springframework.transaction. jta.jtatransactionmanager"> <property name="usertransactionname"> <value>java:comp/usertransaction</value> JavaBean JavaBean JtaTransactionManager JavaBean setbeanfactory org.springframework.beans.factory. BeanFactoryAware void setbeanfactory(beanfactory beanfactory) throws BeansException; Spring BeanFactory JavaBean InitializingBean org.springframework.beans.factory.initializingbean BeanFactory JavaBean BeanFactory InitializingBean JavaBean void afterpropertiesset() throws Exception afterpropertiesset InitializingBean <bean> init-method InitializingBean <bean name="filehelloworld" class="com.openv.spring.helloworld" init-method= init > HelloWorld init 6 JavaBean JavaBean 4 JavaBean Spring JavaBean JavaBean getbean JavaBean 5 JavaBean Spring Web Spring JavaBean 36
3 Spring IoC DisposableBean JavaBean Spring destroy-method JavaBean Spring JavaBean singleton JavaBean prototype JavaBean Spring JavaBean JavaBean Spring JavaBean DisposableBean org.springframework.beans.factory.disposablebean BeanFactory JavaBean BeanFactory DisposableBean JavaBean void destroy() throws Exception destroy DisposableBean <bean> destroy-method DisposableBean <bean name="filehelloworld" class="com.openv.spring.helloworld" destroy-method= destroy > HelloWorld destroy Spring DisposableBean destroy destroy-method 6 Bean Bean <bean> <bean> OO Spring Bean Bean <bean> Tapestry Bean Bean Bean Spring JPetStore 7 PropertyPlaceholderConfigurer PropertyOverrideConfigurer PropertyPlaceholderConfigurer Spring Java LDAP Apache DBCP <bean id="datasource" class="org.apache.commons.dbcp.basicdatasource" destroy-method="close"> <property name="driverclassname"> <value>${jdbc.driverclassname</value> <property name="url"> <value>${jdbc.url</value> 37
Spring <property name="username"> <value>${jdbc.username</value> <property name="password"> <value>${jdbc.password</value> ${jdbc.driverclassname ${jdbc.url ${jdbc.username ${jdbc.password Java <bean id="propertyconfigurer" class="org.springframework.beans.factory.config. PropertyPlaceholderConfigurer"> <property name="location"> <value>jdbc.properties</value> jdbc.properties jdbc.driverclassname=com.mysql.jdbc.driver jdbc.url=jdbc:mysql://localhost/example jdbc.username=sa jdbc.password= PropertyOverrideConfigurer Spring JavaDoc 8 BeanFactoryAware BeanNameAware Spring BeanFactory JavaBean JavaBean BeanFactory JavaBean JavaBean BeanFactoryAware <bean id="datasource" class="org.springframework.jndi.jndiobjectfactorybean"> <property name="jndiname"> <value>java:/mysqlds</value> <bean id="example11servicetarget" class="com.openv.spring.service.impl.example11managerimpl"> <property name="userinfo"> <ref local="userinfodao"/> example11servicetarget datasource Spring 38
3 Spring IoC example11servicetarget datasource BeanFactoryAware Example11ManagerImpl BeanFactoryAware Java BeanFactoryAware JavaBean BeanNameAware org.springframework.beans.factory.beannameaware void setbeanname(string name); InitializingBean afterpropertiesset init-method JavaBean 3.2.2 ApplicationContext BeanFactory JavaBean BeanFactory BeanFactory Spring ApplicationContext ApplicationContext org.springframework.web.context.contextloaderservlet org.springframework.web.context. ContextLoaderListener Web ApplicationContext Spring BeanFactory getbean() JavaBean getbean() JavaBean BeanFactory BeanFactory Spring ApplicationContext ContextLoaderServlet ContextLoaderListener JavaBean ApplicationContext ContextLoaderServlet ContextLoaderListener 3-4 3-5 Log4jConfigServlet Spring ContextLoaderServlet <context-param> <param-name>log4jconfiglocation</param-name> <param-value>/web-inf/classes/log4j.properties</param-value> </context-param> <servlet> <servlet-name>log4jconofigservlet</servlet-name> 39
Spring <servlet-class> org.springframework.web.util.log4jconfigservlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> Spring Web MVC DispatcherServlet 3-4 ContextLoaderServlet 3-5 ContextLoaderListener Log4jConfigListener Spring web.xml <context-param> <param-name>log4jconfiglocation</param-name> 40
3 Spring IoC <param-value>/web-inf/classes/log4j.properties</param-value> </context-param> <listener> <listener-class> org.springframework.web.util.log4jconfiglistener </listener-class> </listener> ApplicationContext BeanFactory J2EE ApplicationContext BeanFactory ApplicationContext 1 Web ApplicationContext BeanFactory ApplicationContext ContextLoaderServlet ContextLoaderListener ApplicationContext ApplicationContext Servlet 2.4 Web ContextLoaderServlet ContextLoaderListener Web ContextLoaderListener example11 <?xml version="1.0"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">. <context-param> <param-name>contextconfiglocation</param-name> <param-value>/web-inf/applicationcontext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.contextloaderlistener </listener-class> </listener> </web-app> Servlet 2.2 Web ContextLoaderServlet Servlet 2.3 Web ContextLoaderListener 41
Spring. <context-param> <param-name>contextconfiglocation</param-name> <param-value>/web-inf/applicationcontext.xml</param-value> </context-param> <servlet> <servlet-name>context</servlet-name> <servlet-class> org.springframework.web.context.contextloaderservlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> 2 ApplicationContextAware Spring Spring ApplicationContext JavaBean JavaBean ApplicationContext JavaBean JavaBean Spring JavaBean <ref> ApplicationContextAware org.springframework.context. ApplicationContextAware void setapplicationcontext(applicationcontext applicationcontext) throws BeansException; <bean id="datasource" class="org.springframework.jndi.jndiobjectfactorybean"> <property name="jndiname"> <value>java:/mysqlds</value> <bean id="example11servicetarget" class="com.openv.spring.service.impl.example11managerimpl"> <property name="userinfo"> <ref local="userinfodao"/> example11servicetarget datasource Spring XML example11servicetarget datasource ApplicationContextAware Example11ManagerImpl ApplicationContextAware Java ApplicationContextAware Example11ManagerImpl ApplicationContextAware 42
3 Spring IoC applicationcontext setter datasource JavaBean Spring ApplicationContext getbean() JavaBean id name import org.springframework.context.applicationcontext; import org.springframework.context.applicationcontextaware; public class Example11ManagerImpl implements ApplicationContextAware { private ApplicationContext applicationcontext; public void setapplicationcontext(applicationcontext applicationcontext){ this.applicationcontext = applicationcontext; public DataSource getdatasource(){ DataSource ds = null; ds = (DataSource)applicationContext.getBean("dataSource"); return ds; BeanFactoryAware 3 ApplicationContext ApplicationContext Spring Spring ApplicationContext 3 ClassPathXmlApplicationContext Web classpath WEB-INF/classes WEB-INF/lib jar Spring ClassPathXmlApplicationContext FileSystemXmlApplicationContext Spring FileSystemXmlApplicationContext XmlWebApplicationContext ContextLoaderListener ContextLoaderServlet Spring 3.3 IoC 3.3.1 发布并监听事件 Spring ApplicationContext BeanFactory 43
Spring Spring Spring org.springframework.context.event.applicationevent org.springframework.context.applicationlistener Observer ApplicationEvent ApplicationContext publishevent Spring ApplicationEvent 3-6 ApplicatinEvent ApplicationContext org.springframework.web.context.support.requesthandledevent Spring WebApplicationContext RequestHandledEvent org.springframework.context.event.contextrefreshedevent Spring ApplicationContext Spring ContextRefreshedEvent org.springframework.context.event.contextclosedevent Spring ApplicationContext Spring ContextRefreshedEvent 3-6 ApplicationEvent Spring ApplicationContext Spring ContextClosedEvent org.springframework.context.support. AbstractApplicationContext public void close() { if (logger.isinfoenabled()) { logger.info("closing application context [" + getdisplayname() + "]"); 44
3 Spring IoC // publish corresponding event publishevent(new ContextClosedEvent(this)); // Destroy all cached singletons in this context, // invoking DisposableBean.destroy and/or "destroy-method". ConfigurableListableBeanFactory beanfactory = getbeanfactory(); if (beanfactory!= null) { beanfactory.destroysingletons(); Spring RequestHandledEvent org.springframework.web.servlet. FrameworkServlet if (ispublishevents()) { // Whether or not we succeeded, publish an event. this.webapplicationcontext.publishevent(new RequestHandledEvent(this, request.getrequesturi(), processingtime, request.getremoteaddr(), request.getmethod(), getservletconfig().getservletname(), WebUtils.getSessionId(request), getusernameforrequest(request), failurecause)); ApplicationEvent JavaBean ApplicationListener public interface ApplicationListener extends EventListener { /** * Handle an application event. * @param event the event to respond to */ void onapplicationevent(applicationevent event); onapplicationevent Spring org.springframework.web.context.support.performancemonitorlistener PerformanceMonitorListener.java public class PerformanceMonitorListener implements ApplicationListener { protected final Log logger = LogFactory.getLog(getClass()); protected final ResponseTimeMonitorImpl responsetimemonitor = new ResponseTimeMonitorImpl(); public void onapplicationevent(applicationevent event) { if (event instanceof RequestHandledEvent) { 45
Spring RequestHandledEvent rhe = (RequestHandledEvent) event; // could use one monitor per URL this.responsetimemonitor.recordresponsetime(rhe.getprocessingtimemillis()); if (logger.isinfoenabled()) { // Stringifying objects is expensive. Don't do it unless it will // show. logger.info("performancemonitorlistener: last=[" + rhe.getprocessingtimemillis() + "ms]; " + this.responsetimemonitor + "; client=[" + rhe.getclientaddress() + "]"); ApplicationListener Spring ApplicationEvent instanceof 3.3.2 自定义 JavaBean 属性编辑器 Spring <property name="transactionattributes"> <props> <prop key="get*"> PROPAGATION_REQUIRED,readOnly </prop> <prop key="set*"> PROPAGATION_REQUIRED </prop> </props> TransactionProxyFactoryBean.java transactionattributes TransactionAttributeSource Spring TransactionAttributeSource JDK JavaBean JDK java.beans.propertyeditor JDK java.beans.propertyeditorsupport PropertyEditor Java TransactionAttributeEditor RuleBasedTransactionAttribute Spring 3-7 Spring FileEditor 46
3 Spring IoC java.io.file 3-7 Spring PropertyEditorSupport setastext() getastext() FileEditor org.springframework.beans.propertyeditors.fileeditor.java public class FileEditor extends PropertyEditorSupport { public void setastext(string text) throws IllegalArgumentException { if (StringUtils.hasText(text)) { setvalue(new File(text)); else { setvalue(null); 47
Spring public String getastext() { if (getvalue()!= null) { return ((File) getvalue()).getabsolutepath(); else { return ""; setastext text File getastext File IoC IoC Spring IoC J2EE IoC Spring Spring 3.4 Spring IoC IoC IoC Spring Spring IoC Spring AOP IoC+AOP J2EE Spring Spring IoC Spring AOP Java/J2EE Spring ApplicationContext Spring AOP 48