今天来说说spring,它有4个关键词,分别是一站式,轻量级,AOP,IOC,一站式通俗来说就是在JavaWeb啥都能做,从web层到service层到Dao层都提供了完整的解决方案,springMVC,spring,JDBCTemplate一条龙,妥妥儿的;spring也是个轻量级框架,几乎不会有代码侵入,且不用依赖太多jar包;AOP,面向切面思想,在实现某一功能时不用改变源代码,在层级面上增加某一功能使用配置文件;IOC意为控制反转,即本来是使用者要做的事情交给程序去做,这里使用了工厂模式,具体实现是创建对象。
一. Spring基本的配置文件如下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用无参构造将Bean类实例化 -->
<bean id="demo" class="com.wekesi.domain.demo" scope="prototype"></bean>
</beans>
约束就不多说了,下面看看具体测试效果
@Test
public void text(){
ApplicationContext app=
new ClassPathXmlApplicationContext("applicationContext.xml");
Demo bean1 = (demo) app.getBean("demo1");
//demo bean2 = (demo) app.getBean("demo");
//System.out.println(bean1==bean2);
//bean1.sd();
System.out.println(bean1.getName());
}
Demo是一个JavaBean类,具有name这么一个属性,这段代码可以输出name属性,可以清晰地看出,我们并没有在测试类里人为地new出对象,而是使用ApplicationContext类来解析XML文件并创建类,这就是IOC思想,那么IOC思想有什么好处呢?它很大程度上解耦了程序,使得程序有了更大的扩展性。举个例子如果我们有很多类需要这个对象,我们就得一个一个人为地new出,一旦JavaBean类有所修改,那么就要在所有类中手动修改,十分麻烦,但是我们如果交给spring来new出对象,只要修改spring中的配置文件就好了,十分方便,这就是解耦的必要性。
接下来我们简单的看看spring框架是怎么实现IOC的,自己写了个类说明一下
public class BeanFactory {
public static Object getObject( String id) {
//解析xml文件
SAXReader reader=new SAXReader();
Document read;
try {
read = reader.read(BeanFactory.class.getClassLoader().getResourceAsStream("Object.xml"));
Element beanElement = (Element) read.selectSingleNode("//bean[@id='"+id+"']");
//获得calss属性的值
String value = beanElement.attributeValue("class");
//反射生成实例
Class clazz = Class.forName(value);
return clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
首先使用dom4j解析XML文件,然后找到id属性对应的class值,通过反射生成实例,这里顺带一提,要求实体类有无参构造方法,这样,就可以通过配置文件的方式获取到类的实例了。
Bean的实例化有三种方式,无参构造,静态工厂,实例工厂,撇开不常用的两种不谈,这里我们只说最常用也是最简单的第一种方式,无参构造方式
<bean id="demo" class="com.wekesi.domain.demo"></bean>
id随便取一个,class中的值为Bean类的全类名,得到实例是用的方法.getBean()中的值即是id值,这样就可以得到Bean类的实例了。
接下来说说XML中的几个属性
1.Scope属性
singleton:创建对象是单例,默认值
prototype:创建对象是多实例
request:创建对象之后,把对象放到request域
session:创建对象之后,把对象放到session域
globalSession:创建对象之后,把对象放到globalSession里面
2.name属性
与id属性相同,不同之处是name属性里可以添加特殊符号,而id属性不行
二. 属性注入
属性注入就是如果Bean类中还有成员变量的话,spring创建对象的时候可以一并为其赋值,方式有三种,set方法注入,有参构造注入和接口注入,spring框架支持前两种
1.有参构造注入
首先在Bean中创建成员变量并给出有参构造方法,如下
package com.wekesi.domain;
public class demo {
private String name;
public demo(String name) {
super();
this.name = name;
}
}
接着在XML文件中配置如下
<!-- 使用有参构造注入属性 -->
<bean id="demo1" class="com.wekesi.domain.demo" >
<constructor-arg name="name" value="小伙子很不错"></constructor-arg>
</bean>
2.set方法注入,与有参构造类似,不过Bean类要提供成员变量的set方法,这里不再赘述,XML配置如下
<!-- 使用set方法注入属性(重点) -->
<bean id="demo1" class="com.wekesi.domain.demo" >
<property name="name" value="haha"></property>
</bean>
3.注入对象属性,这里比较有趣,举个例子,可以使Dao层作为Service层的成员变量存在,并且给出set方法,如下
package com.wekesi.service;
import com.wekesi.dao.Dao;
public class Service {
private Dao dao;
public Dao getDao() {
return dao;
}
public void setDao(Dao dao) {
this.dao = dao;
}
}
XML文件中配置如下
<!-- 创建dao对象 -->
<bean id="Dao" class="com.wekesi.dao.Dao" ></bean>
<!-- 创建service对象 -->
<bean name="service" class="com.wekesi.service.Service">
<!-- 在service里面注入dao属性 -->
<property name="Dao" ref="Dao"></property>
</bean>
这样,如果在controller层创建Service对象则会将Dao层对象也一起创建,因为Dao层对象作为Service对象的属性存在了,这样两行代码就创建了Service层和Dao层对象,十分方便。
至于数组,list集合,set集合和map集合的属性注入与上面相同,都需要提供set方法,XML中配置这里不再详述,小伙伴儿们可自行查阅。时间关系今天就到这里,下次继续Spring。