1、什么是IoC
IoC是一种设计模式,一种设计思想,它的实现一般依赖于JAVA 反射和动态代理技术。
具体解释为控制反转,它意味着将你设计好的类交给系统去控制,而不是在你的类内部控制,这称为控制反转。
2、IoC的好处
比如类A依赖于接口类型为B的某个具体类,一般我们需要在类A中去new一个具体的类对象。但是利用IoC的思想,我们不需要在类A中去直接new一个具体的类对象了,
可以把这个对B接口具体类的依赖的控制权从类A交给平台或者框架去处理,这就是对依赖的控制反转,Spring就使用了这种设计思想。
当我们需要修改这个依赖的具体对象时,我们不需要改具体的业务类的具体代码,而只需更新配置文件即可。
总之,IoC它是面向对象系统设计复杂性和提高面向对象系统可测试性的一个有效的解决方案。
3、IoC的实现技术
IoC的实现技术核心是反射技术,当然它还包括了一些常用的设计模式,如代理模式等,以及XML技术等。
4、一个简单的IoC实现过程
1)创建一个beans.properties文件,用于存放bean的具体实现:
articleDao=bruce.zhao.cms.backend.dao.impl.ArticleDaoImpl
channelDao=bruce.zhao.cms.backend.dao.impl.ChannelDaoImpl
public class PropertiesBeanFactory implements BeanFactory{
//该工厂类产生的bean都放在这个map里面
Map beans=new HashMap();
//默认的properties文件的名字为:beans.properties
private String congfigLocation="beans.properties";
public PropertiesBeanFactory(){
init();
}
public PropertiesBeanFactory(String configLocation){
setCongfigLocation(configLocation);
init();
}
private void init(){
try {
Properties properties=new Properties();
//将properties文件load进来
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(congfigLocation));
//将properties对象转换为一个set,便于遍历
Set set=properties.entrySet();
//循环遍历properties文件里面的一条条记录
for (Iterator iterator=set.iterator(); iterator.hasNext(); ) {
Map.Entry entry=(Map.Entry)iterator.next();
String keyString=(String)entry.getKey();
String className=(String)entry.getValue();
Class clz=Class.forName(className);
Object bean= clz.newInstance();
//将实例化好的类放进map
beans.put(keyString, bean);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public Object getBean(String name){
return beans.get(name);
}
/**
* @return the congfigLocation
*/
public String getCongfigLocation() {
return congfigLocation;
}
/**
* @param congfigLocation the congfigLocation to set
*/
public void setCongfigLocation(String congfigLocation) {
this.congfigLocation = congfigLocation;
}
}
<servlet>
<description></description>
<display-name>InitBeanFactoryServlet</display-name>
<servlet-name>InitBeanFactoryServlet</servlet-name>
<servlet-class>bruce.zhao.cms.backend.view.InitBeanFactoryServlet</servlet-class>
<init-param>
<param-name>configLocation</param-name>
<param-value>beans.properties</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
public class InitBeanFactoryServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public static final String INIT_FACTORY_NAME="_my_bean_factory";
/* (non-Javadoc)
* @see javax.servlet.GenericServlet#init()
*/
@Override
public void init(ServletConfig config) throws ServletException {
BeanFactory beanFactory=null;
String configLocation =config.getInitParameter("configLocation");
if (configLocation==null) {
//如果在web.xml里面没有配置properties文件的名字则
beanFactory=new PropertiesBeanFactory();
}else {
beanFactory=new PropertiesBeanFactory(configLocation);
}
config.getServletContext().setAttribute(INIT_FACTORY_NAME, beanFactory);
}
}
public class BaseServelt extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
*/
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BeanFactory beanFactory=(BeanFactory) getServletContext().getAttribute(InitBeanFactoryServlet.INIT_FACTORY_NAME);
Method[] methods=this.getClass().getMethods();
for (Method method : methods) {
if (method.getName().startsWith("set")) {
String propertyName=method.getName().substring(3);
StringBuffer sb =new StringBuffer(propertyName);
sb.replace(0, 1, (propertyName.charAt(0)+"").toLowerCase());
propertyName=sb.toString();
Object bean= beanFactory.getBean(propertyName);
try {
method.invoke(this, bean);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
super.service(request, response);
}
}
参考:http://whoosh.iteye.com/blog/1133194