Spring 初步认识
- 使现有的技术更加容易使用
- Spring 官网:https://spring.io/projects/spring-framework
- 官方下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring
Spring 的优点
-
一个免费的开源框架
-
一个轻量级的,非入侵式(导入后不会对原来代码产生影响)的框架
-
控制反转(IOC),面向切面编程(AOP)
-
支持事务的处理
在 Spring 中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量
-
方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,相反,Spring 可以降低各种框架的使用难度,Spring 提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持
Spring 组成
- Core 模块:Spring 的核心类库,Spring 的所有功能都依赖于该类库,Core 主要实现 IOC 功能,Sprign 的所有功能都是借助 IOC 实现的
- AOP 模块: Spring 的 AOP 库,提供了 AOP(拦截器)机制,并提供常用的拦截器,供用户自定义和配置
- ORM 模块:提供对常用的 ORM 框架的管理和辅助支持,Spring 支持常用的 Hibernate,ibtas,jdao 等框架的支持,Spring 本身并不对 ORM 进行实现,仅对常见的 ORM 框架进行封装,并对其进行管理
- DAO 模块:提供对 JDBC 的支持,对 JDBC 进行封装,允许 JDBC 使用 Spring 资源,并能统一管理 JDBC 事物,并不对 JDBC 进行实现
- WEB 模块:提供对常见框架如 Struts1,WEBWORK(Struts 2),JSF 的支持,Spring 能够管理这些框架,将 Spring 的资源注入给框架,也能在这些框架的前后插入拦截器
- Context 模块:提供框架式的 Bean 访问方式,其他程序可以通过 Context 访问 Spring 的 Bean 资源,相当于资源注入
- MVC 模块:提供了一套轻量级的 MVC 实现,在 Spring 的开发中,我们既可以用 Struts 也可以用 Spring 自己的 MVC 框架,相对于Struts,Spring 自己的 MVC 框架更加简洁和方便
IOC
- 面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度
- 不需要程序员再去管理对象的创建,可以更加专注的在业务的实现上
- 控制反转 IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现 IOC 的一种方式
- 控制反转是一种通过描述(XML 或注解)并通过第三方去生产或获取特定对象的方式。在 Spring 中实现控制反转的是 IOC 容器,其实现方式是依赖注入(Dependency Injection,DI)
三种引入 Dao 层的方法
手动静态定义
- 程序主动创建对象,控制权在程序员手上,用户的每一个需求都需要程序员修改代码来实现
service 业务层
private UserDao userDao=new MySqlUserDaoImpl();
用户层
public void test(){
UserServiceImpl userService = new UserServiceImpl();
userService.getUser();
}
利用 set 进行动态实现值的注入
- 程序不再主动创建对象,而是被动的接收对象,主动权交给用户,用户的需求不再需要程序员修改代码来实现
service 业务层
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
用户层
public void test(){
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new MySqlUserDaoImpl());
userService.getUser();
}
Spring 方法
- 对象由 Spring 来创建,管理,装配
- 当用户需求发生变化时,只需要对 xml 配置文件进行修改
service 业务层
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用Spring来创建对象,在Spring这些都称为Bean-->
<bean id="mysqlImpl" class="com.yqly.dao.MySqlUserDaoImpl"/>
<bean id="userImpl" class="com.yqly.dao.UserDaoImpl"/>
<bean id="userServiceImpl" class="com.yqly.service.UserServiceImpl">
<!--ref:引用Spring容器中创建好的对象
value:具体的值,基本数据类型-->
<property name="userDao" ref="userImpl"/> <!--根据用户需求修改此处-->
</bean>
</beans>
用户层
public void test1(){
//获得Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象现在都在Spring中管理,使用时直接从里面取出来就可以了
UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("userServiceImpl");
userServiceImpl.getUser();
}
IOC 创建对象的方式
- 默认使用无参构造创建对象
有参构造创建对象的方式
下标赋值创建
<bean id="hello" class="com.yqly.pojo.Hello">
<constructor-arg index="0" value="123"/>
</bean>
通过数据类型创建(多个参数下不建议使用)
<bean id="hello" class="com.yqly.pojo.Hello">
<constructor-arg type="java.lang.String" value="1234"/>
</bean>
通过参数名创建
<bean id="hello" class="com.yqly.pojo.Hello">
<constructor-arg name="name" value="147258"/>
</bean>
Spring 配置
别名
- name:原名
- alias:别名
<alias name="" alias=""/>
Bean 的配置
- id:bean 唯一标识符,也就是相当于我们学的对象名
- class:bean 对象所对应的全限定名:包名 + 类型
- name:也是别名,而且可以同时取多个别名(用逗号/空格/分号隔开)
<bean id="" class="" name=""/>
import
- 一般用于团队开发使用,可以将多个配置文件导入合并为一个总配置文件,
- import:子配置文件名
<import resource=""/>
依赖注入
构造器注入
- 有参构造注入和无参构造注入
Set 方式注入
-
依赖注入:Set 注入
依赖:bean 对象的创建依赖于容器
注入:bean 对象中的所有属性,有容器来注入
复杂类型
@Getter
@Setter
@ToString
public class Address {
private String address;
}
@Getter
@Setter
@ToString
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private Properties info;
private String wife;
}
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.yqly.pojo.Student">
<!--普通值注入——value-->
<property name="name" value="小王"/>
<!--Bean注入——ref-->
<property name="address" ref="address"/>
<!--数组-->
<property name="books">
<array>
<value>西游记</value>
<value>三国演义</value>
<value>红楼梦</value>
<value>水浒传</value>
</array>
</property>
<!--List-->
<property name="hobbies">
<list>
<value>唱歌</value>
<value>跳舞</value>
<value>学习</value>
</list>
</property>
<!--Map-->
<property name="card">
<map>
<entry key="id" value="123456"/>
<entry key="name" value="小王"/>
<entry key="class" value="6班"/>
</map>
</property>
<!--Set-->
<property name="games">
<set>
<value>LOL</value>
<value>DNF</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="id">123456</prop>
<prop key="sex">男</prop>
</props>
</property>
</bean>
</beans>
Student{
name='小王',
address=重庆市,
books=[西游记, 三国演义, 红楼梦, 水浒传],
hobbies=[唱歌, 跳舞, 学习],
card={
id=123456,
name=小王,
class=6班},
games=[LOL, DNF],
info={
sex=男,
id=123456},
wife='null'
}
扩展方式注入
p 命名空间注入
本质还是 Set 注入
- 需要在配置文件中导入约束
xmlns:p="http://www.springframework.org/schema/p"
使用 p 命名空间注入,可以直接注入属性的值
@Getter
@Setter
@ToString
public class User {
private String name;
private int age;
}
<bean id="user" class="com.yqly.pojo.User" p:name="小王" p:age="17"/>
c 命名空间注入
本质还是构造器注入
- 需要在配置文件中导入约束
xmlns:c="http://www.springframework.org/schema/c"
使用 c 命名空间注入,通过构造器注入
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
}
<bean id="user2" class="com.yqly.pojo.User" c:name="小想" c:age="18"/>
Bean 的作用域
单例模式(singleton)(Spring 默认机制)
共享一个对象
<bean id="user" class="com.yqly.pojo.User" c:name="小想" c:age="18" scope="singleton"/>
原型模式(prototype)
每次生成都重新 new 一个对象,放在堆空间,两个地址
<bean id="user2" class="com.yqly.pojo.User" c:name="小想" c:age="18" scope="prototype"/>
其余的只能在 web 开发中使用到