IoC容器
Posted 吴二喵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IoC容器相关的知识,希望对你有一定的参考价值。
一、什么是IoC容器?
Spring核心容器就是一个超级大工厂,所有的对象(包括数据源、Hibernate SessionFactory等基础性资源)都会被当成Spring核心容器管理的对象—Spring把容器中的一切对象统称为Bean。不管该java类是JDK提供的,还是第三方框架提供的,抑或是开发者自己实现的……只要是个java类,并将它配置在配置文件中,spring容器就可以管理它。
IoC容器就是具有依赖注入功能的容器,IoC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IoC容器进行组装。在Spring中BeanFactory是IoC容器的实际代表者。
二、什么是Bean?
Spring中的bean和java bean不同,java bean需要遵守一些特定的规范,而Spring对bean没有要求,只要是一个Java类就可以了。 所以,Bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。
那么Spring容器怎么知道如何管理哪些Bean?
答案是XML配置文件,Spring对XML配置文件的文件名没有任何要求,可以随意指定。当然还可以用注解,这里不做详细介绍。
三、使用Spring容器管理Bean
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.lixing.shop"/>
<!--Jdbc Description -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:jdbc.properties"/>
</bean>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="$jdbc.driverClassName"/>
<property name="url" value="$jdbc.url"/>
<property name="username" value="$jdbc.username"/>
<property name="password" value="$jdbc.password"/>
</bean>
<!--SessionFactory Description -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.lixing.shop.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.mysqlDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<!--HinerbateTemplate Description -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--Transaction Description -->
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--Transaction Advice Desctiption -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="is*" read-only="true"/>
<tx:method name="list*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="upda*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(public * com.lixing.shop.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
</aop:config>
</beans>
Spring框架通过反射根据<bean…/>
元素的class属性指定的类名创建了一个java对象,并以<bean…/>
元素的id属性的值为key,将该对象放入Spring容器中,这个Java对象就成为了Spring容器中的Bean。
下面是一个Spring底层用反射机制将java对象放入Spring容器的伪代码示例:
//解析<bean .../>元素的id属性得到该字符串值为“courseDao”
String idStr = "courseDao";
//解析<bean .../>元素的class属性得到该字符串值为“com.qcjy.learning.Dao.impl.CourseDaoImpl”
String classStr = "com.qcjy.learning.Dao.impl.CourseDaoImpl";
//利用反射知识,通过classStr获取Class类对象
Class<?> cls = Class.forName(classStr);
//实例化对象
Object obj = cls.newInstance();
//container表示Spring容器
container.put(idStr, obj);
在spring配置文件中配置Bean时,class属性的值必须是Bean实现类的完整类名(必须带包名),不能是接口,不能是抽象类(除非有特殊配置),否则spring无法使用反射创建该类的实例。
使用Spring框架后最大的改变之一就是:程序不再使用new调用构造器创建java对象,所有的java对象都是由Spring容器负责创建。
IoC容器的工作步骤:
1、准备配置文件:在配置文件中声明Bean定义也就是为Bean配置元数据。
2、由IoC容器进行解析元数据: IoC容器的Bean Reader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IoC容器根据BeanDefinition进行实例化、配置及组装Bean。
3、实例化IoC容器:由客户端实例化容器,获取需要的Bean。
使用IoC容器的三个基本要点:
1、应用程序的各个组件面向接口编程,将组件之间的耦合关系提升到接口层次,有利于项目后期的扩展
2、应用程序的各组件不再由程序主动创建,而是由Spring容器来负责产生并初始化
3、Spring采用配置文件或者注解来管理Bean的实现类、依赖关系,Spring容器则根据配置文件或注解,利用反射来创建实例,并为之注入依赖关系。
以上是关于IoC容器的主要内容,如果未能解决你的问题,请参考以下文章