Soring是分层的javaSE/EE应用full_stack(全站)轻量级开源框架,以loc(inverse Of Contorl:反转控制)和AOP(面向切面编程)为内核。
Spring提供了(展现层SpringMVC)和(持九层SpringJDBCTemplate)以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的javaEE企业应用开源框架。
第一步:创建Dao层
UserDao接口:
public interface UserDao {
public void save();
}
接口实现类:
public class UserDaoimpl implements UserDao {
@Override
public void save() {
System.out.println("........");
}
}
第二步:创建service层
UserService接口:
public interface UserService {
public void save();
}
接口实现类:
public class UserServiceimpl implements UserService {
private UserDao userDao = new UserDaoimpl();
@Override
public void save() {
userDao.save();
}
}
第三步:测试代码
public class UserTest {
private UserService userService = new UserServiceimpl();
@Test
public void test() {
userService.save();
}
}
测试结果:
........
进程已结束,退出代码0
第一步:导入 Spring 开发的基本包坐标
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
第二步:创建Dao层
这里接口和实现类代码和原始开发相同就略过
第三步:创建 Spring 核心配置文件,在配置文件中配置 UserDaoImpl
applicationContex.xml文件
<?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">
<bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
</beans>
第四步:使用 Spring 的 API 获得 Bean 实例进行测试
public class userTest {
public static void main(String[] args) {
//获得 Bean 实例
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
//
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.save();
}
}
测试结果
用于配置对象由Spring来创建,默认情况下调用的是类中的无参构造函数,如果没有无参构造函数则创建失败。
基本属性:
id:Bean实例在Spring容器中的唯一标识
class:Bean的全限定名称
scope:指对象的作用范围,具体取值有:
按例:
在Bean中加入scope属性:
<bean id="userDao" class="com.dao.impl.UserDaoimpl" scope="singleton"/>
测试代码:
@Test
//测试scope属性
public void test1() {
//获得 Bean 实例
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");
UserDao userDao2 = (UserDao) app.getBean("userDao");
System.out.println(userDao1);
System.out.println(userDao2);
}
其它代码保持不变,将singleton改为prototype时运行结果为:
地址不一样代表现在容器中存在多个对象。
结论:
当scope="singleton"时,Spring核心文件被加载时,创建Bean
- 对象创建:当应用加载,创建容器时,对象就被创建
- 对象运行:只要容器在,对象一直活着
- 对象销毁:当应用卸载,销毁容器时,对象就被销毁
当scope="prototype"时,每调用一次getBean()方法就创建一个bean
- 对象创建:当使用对象时,创建新的对象实例
- 对象运行:只要对象在使用中,就一直活着
- 对象销毁:当对象长时间不用时,就会被java的垃圾回收器回收
init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称
按例:
在Dao实现类(在原基础上加了两个方法):
public class UserDaoimpl implements UserDao {
public UserDaoimpl() {
System.out.println("UserDaoimpl创建");
}
public void init() {
System.out.println("初始化方法");
}
public void destroy() {
System.out.println("销毁方法");
}
@Override
public void save() {
System.out.println("........");
}
}
核心配置文件为:
<bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
在不做其他操作下运行结果为:
<bean id="userDao" class="com.dao.impl.UserDaoimpl" init-method="init" destroy-method="destroy"/>
创建一个对象工厂类,里有一个静态方法:
public class StaticFactory {
public static UserDao getUserDao() {
return new UserDaoimpl();
}
}
配置文件该改为:
<bean id="userDao" class="com.factory.StaticFactory" factory-method="getUserDao"/>
案例:
创建一个工厂类:
public class DynamicFactory {
public UserDao getUserDao() {
return new UserDaoimpl();
}
}
配置如下:
<bean id="factory" class="com.factory.DynamicFactory" />
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"/>
前面的按例是让Spring去实例化Dao层的对象,下面将以web层和业务层来进行讲解。
按例:
Service实现类:
public class UserServiceimpl implements UserService {
@Override
public void save() {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.save();
}
}
相关配置:
<bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
<bean id="userService" class="com.service.impl.UserServiceimpl"/>
在web层创建一个类进行测试:
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
UserService userService = (UserService) app.getBean("userService");
userService.save();
}
}
测试结果:
由案例可知,userDao和userService都存在于Spring容器中,当Service层要用到Dao层就要从容器中获取,而web层只对Service进行操作如下图所示。
因为UserService和UserDao都在Spring容器中,而最终程序直接使用的是UserService,所以可以在Spring容器中,将UserDao设置到UserService内部,这时候就要用到依赖注入了,如下图所示。
依赖注入概念:依赖注入是Spring框架核心IOC的具体实现
依赖注入方式(将UserDao注入到UserService内部):
1、构造方法
按例:
在service的实现类中生成有参构造方法:
public class UserServiceimpl implements UserService {
private UserDao userDao;
public UserServiceimpl(UserDao userDao) {
this.userDao = userDao;
}
public UserServiceimpl() {
}
@Override
public void save() {
userDao.save();
}
}
配置文件中的配置:
<bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
<bean id="userService" class="com.service.impl.UserServiceimpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
测试运行结果略
2、set方法
按例:
将service的实现类改为:
public class UserServiceimpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
在配置文件中将userDao注入给userService,配置文件为:
<bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
<bean id="userService" class="com.service.impl.UserServiceimpl">
<property name="userDao" ref="userDao"></property>
</bean>
除了上面的配置方法还有一种较简单的配置方法p命名空间注入:
先引入p命名空间,再修改注入方式,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
//p命名空间
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
//注入对象
<bean id="userService" class="com.service.impl.UserServiceimpl" p:userDao-ref="userDao"></bean>
</beans>
运行结果和前面相同就略过了
前面都是通过对象的引用进行注入的,除了引用数据类型之外还可以注入普通数据类型、集合数据类型。
普通数据类型注入按例:
在Dao实现类中设置两个属性:
public class UserDaoimpl implements UserDao {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void save() {
System.out.println(name+"==="+age);
System.out.println("........");
}
}
配置文件配置如下:
<bean id="userDao" class="com.dao.impl.UserDaoimpl">
<property name="name" value="tom"/>
<property name="age" value="18"/>
</bean>
public class UserDaoimpl implements UserDao {
private List<String> stringList;
private Map<String, User> userMap;
private Properties properties;
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void save() {
System.out.println(stringList);
System.out.println(userMap);
System.out.println(properties);
System.out.println("........");
}
}
配置文件配置:
<bean id="userService" class="com.service.impl.UserServiceimpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
<bean id="userDao" class="com.dao.impl.UserDaoimpl">
<property name="stringList" >
<list>
<value>招财</value>
<value>进宝</value>
</list>
</property>
<property name="userMap">
<map>
<entry key="1:" value-ref="user1"></entry>
<entry key="2:" value-ref="user2"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="欠债">还钱</prop>
<prop key="杀人">偿命</prop>
</props>
</property>
</bean>
<bean id="user1" class="com.domain.User">
<property name="name" value="荣华"/>
<property name="age" value="18"/>
</bean>
<bean id="user2" class="com.domain.User">
<property name="name" value="富贵"/>
<property name="age" value="18"/>
</bean>
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载
<import resource="XXXX.xml"/>
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
UserService userService = (UserService) app.getBean("userService");
userService.save();
}
}
applicationContext:接口类型,代表应用上下文,可以通过其实例获得Spring容器中的Bean对象
1、ClassPathXmlApplicationContext:
从类的根路径下加载配置文件推荐使用
2、FileSystemXmlApplicationContext:
从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
3、AnnotationConfigApplicationContext:
使用注解配置容器对象时,需要使用此类来创建spring容器。它用来读取注解
如果有多个相同Bean时用id的方式,如果只有一个Bean时用Class方式。
1、方便解耦,简化开发
通过Spring提供的IOC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度耦合。用户也不必在为单例模式类、属性文件解析等这些很底层的需求代码,可以专注于上层应用
2、AOP编程的支持
通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松实现
3、声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式进行事务管理,提高开发效率好质量
4、方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情
5、方便集成各种优秀框架
Spring对各种优秀框架的支持
6、降低JavaEE API的使用难度
Spring对JavaEE API进行了封装,使这些API的使用难度大为降低
7、Java源码是经典学习范例