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容器