0 前言
Spring的目的就是用来简化企业开发,降低代码之间的耦合度。
1 文件结构
使用Maven项目构建的目录,这里只涉及到service层和dao层,有两个运行程序的入口,分别是AppSingle用来获取单例的bean对象,一个是AppProto用来获取多个类型相同的bean对象。
2 容器相关
Spring中最核心的就是IoC容器和DI依赖注入了,这个部分是有关容器的部分。
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!--name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔-->
<bean id="xglService" name="service service4 bookEbi" class="com.xlg.service.impl.XglServiceImpl">
<property name="xglDao" ref="xglDao"/>
</bean>
<!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype-->
<bean id="xglDao" name="xgl" class="com.xlg.dao.impl.XlgDaoImpl" scope="prototype"/>
</beans>
上述代码为applicationContext.xml中的配置信息,最主要的作用就是用来配置bean和管理bean对象了(可以把它想象成spring容器,管理了很多bean标签的对象)。其中或者就代表一个bean标签,用来生成一个bean对象,标签中各种属性代表的含义如下:
2.1 获取bean
使用ApplicationContext接口和对应的实现类ClassPathXmlApplicationContext加载配置好的xml文件来获取bean对象,代码如下:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
XglService xglService = (XglService) ctx.getBean("xglService");
这里需要注意两个地方:如果使用ApplicationContext获取bean时,在调用getBean方法之前就已经初始化IoC容器中的bean对象了(执行了放入容器中bean对象的无参构造函数),但是如果使用更抽象的接口BeanFactory的话,有如下代码:
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
XglService xglService = (XglService) ctx.getBean("xglService");
这样就会延迟加载bean,即如果不调用getBean方法的话,就不会初始化容器中的bean,若想要使用第一种方式(ApplicationContext)也达到(BeanFactory)的效果,则需要设置相关bean标签中的lazy-init属性值为"true"。
3 依赖注入(DI)
一开始学习这个东西感觉很懵,现在也没有很深入的理解。既然第二部分是管理bean的,但是在一般的工程项目中不可能总是去调用单个bean对象,肯定需要建立不同bean对象之间的关系,所以DI我就简单的理解为建立bean与bean之间的关系。
在文件结构当中,我想要通过XglServiceImpl这个实现类实现XglService接口中的save方法,而在dao层中XlgDaoImpl这个实现类中也有一个save方法,是用来实现XlgDao的接口的。假设我要分别调用这两个实现类来实现这两个方法那么配置文件和入口函数代码可以这样写:
<!-- 配置文件信息:产生XglServiceImpl和XlgDaoImpl两个对象-->
<bean id="xglService" name="service" class="com.xlg.service.impl.XglServiceImpl"/>
<bean id="xglDao" name="dao" class="com.xlg.dao.impl.XlgDaoImpl" />
// XglDao中的方法
public interface XglDao {
public void save();
}
// XglService中的方法
public interface XglService {
public void save();
}
// XlgDaoImpl中的方法
public class XlgDaoImpl implements XglDao {
public void save() {
System.out.println("实现了Xlg的接口");
}
}
//XglServiceImpl中的方法
public class XglServiceImpl implements XglService {
public void save() {
System.out.println("实现了XglService的接口");
}
}
public class AppSingle {
public static void main(String[] args) {
//入口函数:分别实现XglService和XglDao中的save方法
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
XglService xglService = (XglService) ctx.getBean("xglService");
XglDao xglDao = (XglDao) ctx.getBean("xglDao");
xglService.save();
xglDao.save();
}
}
//输出结果
实现了XglService的接口
实现了Xlg的接口
上述代码完成了两个bean对象的单独使用。现在我想通过XglServiceImpl调用XlgDaoImpl的方法,就使得两个bean对象产生了关系,所以就需要进行依赖注入(DI)了。
首先,要在XglServiceImpl实现类中设置XlgDao类型的属性,然后调用这个属性的方法save,代码如下:
public class XglServiceImpl implements XglService {
private XglDao xglDao; //XglDao的属性
public void setXglDao(XglDao xglDao) { //XglDao的setter方法
this.xglDao = xglDao;
}
public void save() {
System.out.println("实现了XglService的接口");
xglDao.save(); //调用XglDao的方法
}
}
添加了三个代码行,但是这样还不能调用到XglDao的save方法,因为XglDao只是一个接口,还需要实现类来实现他,所以我们还要在xml文件中添加配置信息:
<bean id="xglService" name="service service4 bookEbi" class="com.xlg.service.impl.XglServiceImpl">
<property name="xglDao" ref="xglDao"/>
</bean>
<bean id="xglDao" name="xgl" class="com.xlg.dao.impl.XlgDaoImpl"/>
这里添加的就是注入两个bean的依赖关系,使得XglServiceImpl能够找到XlgDaoImpl从而实现XglDao的save方法。注意:ref中的xglDao是XlgDaoImpl中的id,name是XglServiceImpl类中的xglDao属性。至此,完成了一个依赖注入,来看看程序的运行结果:
public class AppSingle {
public static void main(String[] args) {
//入口函数:分别实现XglService和XglDao中的save方法
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
XglService xglService = (XglService) ctx.getBean("xglService");
xglService.save();
}
}
实现了XglService的接口
实现了Xlg的接口
实现了通过XglService对象调用XglDao对象的方法。