Spring IOC概念及模拟实现

原文链接:http://jinnianshilongnian.iteye.com/blog/1413846

http://jinnianshilongnian.iteye.com/blog/1413846

1. 什么是IOC?

IoC(Inversion of Control,控制反转)。这是spring的核心,贯穿始终。所谓IoC,什么被反转了?获得依赖对象的方式反转了。对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。
其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

2. 什么是DI?

DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。

3. 模拟IOC 实现(手写类似的实现)

https://blog.csdn.net/Anger_Coder/article/details/12706277
XML文件略过了,直接看实现

public class ClassPathXmlApplicationContext implements BeanFactory
{
	private Map<String, Object> beans = new HashMap<String, Object>();	//IoC容器
	
	public ClassPathXmlApplicationContext() throws Exception
	{
		SAXBuilder builder = new SAXBuilder();
		Document document = builder.build( this.getClass().getClassLoader().getResource( "resource/beans.xml" ) );
		
		Element root = document.getRootElement();
		
		List<Element> list = root.getChildren( "bean" );				// 获得所有的bean的Element
		
		for( int i = 0; i < list.size(); i++ )
		{
			Element element = (Element)list.get( i );
			
			String  id    = element.getAttributeValue( "id" );			
			String  clazz = element.getAttributeValue( "class" );
			
			System.out.println( id + " : " + clazz );
			Object obj = Class.forName( clazz ).newInstance();			// 1th.实例化Bean对象
			beans.put( id, obj );
			
			/**
			 * 	<bean id="u" class="com.hzy.dao.impl.UserDAOImpl"/>
	
				<bean id="userService" class="com.hzy.service.UserService">
					<property name="userDAO" bean="u"/>
				</bean>
			 */
			// 2th.注入依赖
			// 获得所有property属性
			for( Element propertyElement : (List<Element>)element.getChildren( "property" ) )
			{
				String name       = propertyElement.getAttributeValue( "name" );	// userDAO
				String injectBean = propertyElement.getAttributeValue( "bean" );	// u;
				Object propertyObj = beans.get( injectBean );
				
				// 3th.拼接userService中 userDAO属性 的 setter方法
				// name.substring( 0, 1 ).toUpperCase() 将 u 变成大写
				String methodName = "set" + name.substring( 0, 1).toUpperCase() + name.substring( 1 );
				
				System.out.println( "method name = " + methodName );
				
				/**
				 * getMethod 会返回对象的方法..这个方法来自对象的公开方法或接口		反射机制
				 * Returns a Method object that reflects the specified 
				 * public member method of the class or interface represented by this Class object. 
				 */
				Method m = obj.getClass().getMethod( methodName, propertyObj.getClass().getInterfaces() );
				// 4th.注入
				m.invoke( obj, propertyObj );
			}
		}
	}
	
	@Override
	public Object getBean( String name ) 
	{
		return beans.get( name );
	}
}
上一篇:创建一个Spring项目


下一篇:@Autowired 是通过类型查找还是通过属性名查找?