一、Spring的最核心的思想
(1).控制反转(IOC):以前传统的java开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象,而在Spring开发模式中,Spring容器使用了工厂模式为我们创建了所需要的对象,我们使用时不需要自己去创建,直接调用Spring为我们提供的对象即可,这就是控制反转的思想。实例化一个java对象有三种方式:使用类构造器,使用静态工厂方法,使用实例工厂方法,当使用Spring时我们就不需要关心通过何种方式实例化一个对象,Spring通过控制反转机制自动为我们实例化一个对象。
(2).依赖注入(DI):Spring使用javaBean对象的Set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程就是依赖注入的基本思想。
(3).面向切面编程(AOP):在面向对象编程(OOP)思想中,我们将事物纵向抽象成一个个的对象。而在面向切面编程中,我们将一个个对象某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事务管理,记录日志等通用操作处理的过程就是面向切面编程的思想。
二、Spring管理JavaBean对象的方式
在Spring中,所有管理的对象都是JavaBean对象,而BeanFactory和ApplicationContext就是spring框架的两个IOC容器,现在一般使用ApplicationnContext,其不但包含了BeanFactory的作用,同时还进行更多的扩展。
模拟ApplicationnContext实现方式:
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
/**
* 模拟ApplicationContext实现
* @author Anndy
*/
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String , Object> beans = new HashMap<String, Object>();
//IOC Inverse of Control DI Dependency Injection
public ClassPathXmlApplicationContext() throws Exception {
SAXBuilder sb=new SAXBuilder();
Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //构造文档对象
Element root=doc.getRootElement(); //获取根元素HD
List list=root.getChildren("bean");//取名字为disk的所有元素
for(int i=0;i<list.size();i++){
Element element=(Element)list.get(i);
String id=element.getAttributeValue("id");
String clazz=element.getAttributeValue("class");
Object o = Class.forName(clazz).newInstance();
System.out.println(id);
System.out.println(clazz);
beans.put(id, o);
for(Element propertyElement : (List<Element>)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name"); //userDAO
String bean = propertyElement.getAttributeValue("bean"); //u
Object beanObject = beans.get(bean);//UserDAOImpl instance
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
System.out.println("method name = " + methodName);
Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
m.invoke(o, beanObject);
}
}
}
public Object getBean(String id) {
return beans.get(id);
}
}
以上是简单的模拟Spring中ApplicationContext的实现方式。
1、实例化IOC容器的两种方式:
ApplicationContext方式:
//如果只有一个spring配置文件也可以直接传递一个string参数,不需要使用数组
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{“spring配置文件路径”});
BeanFactory方式:
Resource res = new FileSystemResource(“spring配置文件”);
BeanFactory factory = new XMLBeanFactory(res);
2、Spring配置文件的方法
一般情况、由于Spring需要管理和配置的东西比较多,如果都放在一个配置文件中,配置文件会变的比较大,同时不方便与维护,一般好的做法是按照功能模块将Spring配置文件分开,例如:DAO层配置到一个spring-dao.xml配置文件中,Service层配置到spring-service.xml文件中,Struts的action配置到spring-action.xml文件中。
在一个作为Spring总配置文件中的<bean>元素定义之前,通过<import>元素将要引入的spring其他配置文件引入,例如:
<beans>
<import resource=”spring-dao.xml”/>
<import resource=”spring-service.xml”/>
<import resource=”spring-action.xml”/>
……
<bean>
</bean>
……
</beans>
2.1、 Spring配置文件bean的配置规则:
(1)一个Bean可以通过一个id属性惟一指定和引用,如果Spring配置文件中有两个以上相同的id时,Spring会报错id冲突。
(2)一个Bean也可以通过一个name属性来引用和指定,如果Spring配置文件中有两个以上相同name的Bean,则Spring通过name引用时,运行时后面的会自动覆盖前面相同name的bean引用,而不会报错。
2.2、Spring依赖注入bean的方式
对于Spring配置一个bean时,如果需要给该bean提供一些初始化参数,则需要通过依赖注入方式,所谓的依赖注入就是通过Spring将bean所需要的一些参数传递到bean实例对象的过程,Spring的依赖注入有3种方式:
(1)构造方法注入
<bean id=”……” class=”……”>
<constructor-arg>构造函数需要的参数1</constructor-arg>
<constructor-arg>构造函数需要的参数2</constructor-arg>
……
</bean>
(2)setter方法注入
<bean id=”……” class=”……”>
<property name=”属性1” value=”……”/>
<property name=”属性2” value=”……”/>
……
</bean>
(3)Field字段注入
Spring2.5以后提供的基于java 注解(annotation)方式的注入,就是在java中的字段上或者setter方法上通过使用注解方式进行Spring的依赖注入。
a、字段注入;b、属性注入
2.3、Spring通过注入方式注入bean的方式
Spring中为一个bean注入其依赖的另一个bean时,通过使用ref来注入另一个bean,例子如下:
<beans>
<bean id=”bean1” class=”……”>
<property name=”属性1” value=”……”/>
……
</bean>
<bean id=”bean2” class=”……”>
<property name=”bean1” ref=”bean1”/>
……
</bean>
</beans>
2.4、Spring的集合注入:
a、Set集合注入;b、List集合注入;c、Map集合注入;d、Properties注入
注意:Spring会自动将其数据类型转换,支持泛型。
以上是Spring通过配置文件的方式实现JavaBean注入。
下一篇会讲如何使用注解的方式实现JavaBean注入。