Spring 是 Java Web 开发过程中使用较为广泛的框架,该框架是一个轻量级的应用框架,其强大的功能以及卓越的性能而受到众多开发人员的喜爱。
在实际项目开发过程中,将服务器分为三层:表现层(Web)、业务逻辑层(Service)、持久层(Dao),在目前主流的开发框架中,Spring对每一层都有独到的处理方式,如在表现层在表现层提供了与 Struts2 框架的整合,持久层中提供了jdbcTemplate技术,在业务逻辑层提供了事物管理和日志记录等。
今天讲述的是Spring在业务逻辑层的相关知识。
1.方便解耦,简化开发,通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
2.AOP 编程的支持通过 Spring 的 AOP 功能,方便进行面向切面的编程。
3声明式事务的支持可以将我们从单调烦闷的事务管理代码中解脱出来,通过 声明式方式灵活的进行事务的管理,提高开发效率和质量。
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。
耦合指的就是就是对象之间的依赖性。对象之间的耦合越高,维护成本越高。
此处通过一段代码来说明:
在上面的代码当中我们可以看到注册驱动有可以有两种方式,第一种是利用new的形式去注册驱动,第二种是我们熟悉的Class.forname(com.mysql.jdbc.Driver)的形式,实际上是利用反射。
那么我们为什么在注册驱动的时候选择利用第二种方式呢?
原因在于我们的注册驱动是有不同的,mysql的是一种驱动,Oracle的驱动是一种,如果我们按第一种形式new出来,显然把它写死了,也就是说我们这种代码类跟类之间的依赖程度更高,耦合度更大。
在我们实际开发中,往往要求我们写代码的质量更高,耦合度更低,这样更符合我们实际开发的要求,而使用Spring的框架可以满足我们这一想法。
IOC的概念:
IOC全称-Inversion Of Control,中文为控制反转。在之前我们开发的思想是需要某个对象,我们就去把这个对象new出来供自己使用,这个过程是自我直接的、主动的。
现在,我们可以通过工厂的模式,把对象new出来这一步骤交给工厂,当我们需要某个对象的时候,就可以同时向工厂要,有工厂为我们查找或者创建对象。是被动的。
这种被动接收的方式获取对象的思想就是控制反转,它是 spring 框架的核心之一。即将创建对象的权利交给工厂来创建,从而降低开发的耦合度。
开发工具:IntelliJ IDEA ,如未激活idea请看:idea的激活方法
Maven工程:这里使用Maven创建模块,如未安装、配置请看:Maven的安装及配置
当我们有了Maven的时候就无需再次下载Spring相关jar包,直接定位即可。
利用Spring的IOC来降低代码的耦合度,模拟使用保存方法的步骤,在写的过程中减少使用new的形式,提高代码的质量。
案例使用bean.xml的形式配置,让spring的bean标签完成对象创建、存活、销毁。
1.利用Maven直接创建模块
2.导入Spring坐标:
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
3.创建实体类User,设置三个属性,并生成get和set方法:
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4.创建逻辑层的实现类和接口
5.创建配置文件:Bean.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">
<!--把对象的创建交给spring来管理-->
<bean id="UserService" class="com.pale.Service.impl.USerServiceImpl"></bean>
</beans>
public class ul {
public static void main(String[] args) {
ApplicationContext cs = new ClassPathXmlApplicationContext("bean.xml");
UserService userService = (UserService)cs.getBean("UserService");
userService.savaAll();
}
}
至此,相关的创建和代码已经完成,当我们点击运行时可以有如下的效果:
bean标签的使用:
将所需要用于配置对象让 spring 来创建,无需我们在手动打代码,如此处的UserService及实现类。
bean标签中的属性:
id:给对象在容器中提供一个唯一标识。用于获取对象。此处为UserService
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。此处为UserServiceImpl
scope:指定对象的作用范围。
bean标签的生命周期:
当scope="singleton"时,此时为单例对象,创建的对象生命周期与容器息息相关。当容器创建时就创建对象,只要容器存在对象就不会被销毁,只有当容器关闭时才会将对象销毁。
当scope="prototype"时,此时为多例对象,是有延迟的,当需要访问对象时,就会重新创建对象。即当使用对象时,才会创建新的对象实例,只要对象在使用中,就一直活着。当对象长时间不用时,被 java 的垃圾回收器回收了。
实例化bean对象的方式:
1.默认方式:如案例则为默认方式,它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。
<!--把对象的创建交给spring来管理-->
<bean id="UserService" class="com.pale.Service.impl.USerServiceImpl"></bean>
2.使用静态工厂的形式来实例化bean对象:
2.1创建工厂类
public class StaticFactory {
public static UserService createAccountService(){
return new USerServiceImpl();
}
}
2.2在bean.xml中配置为:
<bean id="UserService" class="com.pale.factory.StaticFactory" factory-method="createUserService"></bean>
这时,也可以正常的运行代码。
3.使用管理实例工厂的模式实例化bean:
3.1 创建工厂类 (同类似2.1)
public class InstanceFactory {
public UserService createUserService(){
return new USerServiceImpl();
}
}
3.2在bean.xml中配置为:
<bean id="InstanceFactory" class="com.pale.factory.InstanceFactory"></bean>
<bean id="UserService" factory-bean="InstanceFactory" factory-method="createUserService"></bean>
概念:Dependency Injection。
它是 spring 框架核心 ioc 的具体实现。
在我们编写代码过程中虽然可以通过spring来降低耦合度,但是类与类之间还是存在依赖的,这种依赖是无法消除的。例如逻辑层还是会调用持久层来去完成数据库的操作。
所以简单的来说,依赖注入就是把这种依赖关系交由Spring去管理和维护,不需要我们再去编写更多的代码。
方式:
依赖注入的方式分为利用构造函数注入、set方法注入,此处讲解set方法的注入。
1.在逻辑层实现类里增加属性:username,password,birthday,生成对应的set方法,并且将结果打印。
public class USerServiceImpl implements UserService {
private String username;
private String password;
private Date birthday;
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void savaAll() {
System.out.println(username+","+password+","+birthday);
}
}
2.配置bean.xml文件为:
<bean id="UserService" class="com.pale.Service.impl.USerServiceImpl">
<property name="username" value="有点意思"></property>
<property name="password" value="root"></property>
<property name="birthday" ref="now">
</property>
</bean>
<bean id="now" class="java.util.Date"></bean>