IOC容器自動管理須要使用的Bean,提升代碼的重用性,同時也達到解耦的目的,IOC實現Bean管理的方式主要是依靠動態代理和反射機制原理,使用動態代理可直接代理目標Bean,實現Bean的高效管理,動態代理可代理目標接口實現Spring框架的攔截器、通知等AOP功能,實現Bean在IOC容器裏面的全局管理,反射機制主要用於Bean的自動生成,當程序須要使用IOC容器中的Bean時,IOC會根據applicationContext.xml Bean的配置狀況經過反射機制自動生成Bean,供外部調用,同時IOC容器提供對Bean的做用域、生命週期等管理。java
2種IOC容器:BeanFactory/ApplicationContextmysql
BeanFactory:主要提供一些IOC的基本功能,像對配置文件的屬性值填充的高級功能,BeanFactory是沒法處理的linux
ApplicationContext: 雖然也是實現BeanFactory接口,可是其的工做方式和BeanFactory略有不一樣,例如ApplicationContext在處理配置文件時能夠一次性處理多個,從而實現整個項目的功能模塊化開發,常見的Web項目中Spring、Springmvc、shiro等框架都配置獨立的配置文件,經過ApplicationContext可處理多個配置文件特性,在Spring框架的總控配置文件中引入達到模塊聚合的效果,相似Maven中的Modules功能(BeanFactory的高級版本)spring
applicationContext.xml:sql
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- bean分散配置,經過設置property-placeholder設置屬性文件, 並在實際bean初始化時使用$佔位符引出處理,context在spring容器視爲bean(特殊) <context:property-placeholder location="com/zhiwei/dispatch/database.properties,com/zhiwei/ioc/databaseBack.properties"/> --> <!-- 引入多個屬性文件的另外一種形式 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:com/zhiwei/ioc/database.properties</value> <value>classpath:com/zhiwei/ioc/databaseBack.properties</value> </list> </property> </bean> <bean id="database" class="com.zhiwei.ioc.Database" > <property name="databaseName" value="${databaseName}"/> <property name="driverName" value="${driverName}"/> <property name="url" value="${url}"/> <property name="userName" value="${userName}"/> <property name="passwd" value="${passwd}"/> </bean> <bean id="databaseBack" class="com.zhiwei.ioc.Database" name="aliaseName" scope="prototype" > <property name="databaseName" value="${databaseNameBack}"/> <property name="driverName" value="${driverNameBack}"/> <property name="url" value="${urlBack}"/> <property name="userName" value="${userNameBack}"/> <property name="passwd" value="${passwdBack}"/> </bean> </beans>
數據庫屬性封裝類:Database.java數據庫
package com.zhiwei.ioc; //數據庫參數配置類 public class Database { private String databaseName; private String driverName; private String url; private String userName; private String passwd; public String getDatabaseName() { return databaseName; } public void setDatabaseName(String databaseName) { this.databaseName = databaseName; } public String getDriverName() { return driverName; } public void setDriverName(String driverName) { this.driverName = driverName; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } @Override public String toString() { return "Database [dabaseName=" + databaseName + ", driverName=" + driverName + ", url=" + url + ", userName=" + userName + ", passwd=" + passwd + "]"; } }
數據庫測試屬性配置文件:database.properties、databaseBack.properties緩存
databaseName=MySql driverName=jdbc\uFF1Amysql\:mysqlDriver url=com.mysql.jdbc\://127.0.0.1.1\:1433/test userName=root passwd=xiaoyang
databaseNameBack=MySqlBack driverNameBack=jdbc\uFF1Amysql\:mysqlDriverBack urlBack=com.mysql.jdbc\://127.0.0.1.1\:1433/testBack userNameBack=rootBack passwdBack=xiaoyangBack
BeanFactory容器測試類:安全
package com.zhiwei.ioc; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; /*** * BeabFactory容器的缺陷: * ①:不會解析${userName}相似的表達式,只會直接獲取property標籤裏面value的文本值 * @author Yang Zhiwei * */ public class BeanFactoryIOC { @SuppressWarnings("unused") public static void main(String[] args) { //StringUtils.cleanPath:格式化linux形式的文件路徑:\\-->/ 開頭不須要/ XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("com/zhiwei/ioc/applicationContext.xml")); String[] aliases=beanFactory.getAliases("databaseBack"); //獲取bean的別名 System.out.println("beanName別名:"+aliases[0]); String[] beforeBeanNames=beanFactory.getSingletonNames(); System.out.println("beforeBeanNames:"+beforeBeanNames.length); //注意只有在IOC容器裏面的Bean被使用的時候纔會進行註冊:標記該類已經實例化可使用 Database db=(Database) beanFactory.getBean("database"); Database dbback=(Database) beanFactory.getBean("databaseBack"); System.out.println(db); //由於databaseBack設置爲prototype的做用域,所以只能獲取單例的database的數據 String[] afterBeanNames=beanFactory.getSingletonNames(); System.out.println("afterBeanNames:"+afterBeanNames.length); System.out.println(beanFactory.containsLocalBean("database")); //bean工廠是否包含bean } }
結果:服務器
BeanFactory是沒法對${}引用資源文件變量進行解析處理mvc
ApplicationContext測試類:
package com.zhiwei.ioc; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /*** * Spring IOC容器的兩種實現方式: * 簡單:BeanFactory 複雜:ApplicationContext * @author Yang Zhiwei * */ public class MainTest { public static void main(String[] args) { /* *將屬性文件注入IOC容器,並經過Javabean的形式獲取 *通常用來放置配置文件,進行初始化操做 */ ApplicationContext ac=new ClassPathXmlApplicationContext("com/zhiwei/ioc/applicationContext.xml"); Database db=(Database) ac.getBean("database"); Database dbBack=(Database) ac.getBean("databaseBack"); System.out.println(db); System.out.println("數據庫:"+db.getDatabaseName()); System.out.println("數據庫Back:"+dbBack.getDatabaseName()); } }
結果:
ApplicationContext 可對 ${} 引用資源文件變量的形式解析處理,在大型的項目開發中,不一樣的框架都具備各自的配置文件,若是所有硬塞在一個總的配置文件中對於後續的項目維護絕對是一場噩夢,RDBMS配置文件、數據庫配置文件、緩存服務器配置文件、緩存框架配置文件、安全框架配置文件、MVC框架配置文件等等,由於BeanFactory的性能弱的緣由,如今的Spring項目中ApplicationContext是首選IOC容器