Spring系列
- Spring — Spring简介、入门、配置 , IoC和DI思想
- Spring — IoC核心(基于XML)、DI核心(基于XML)
- Spring — 使用IoC和DI模拟注册案例、注解配置IoC和DI
- Spring — 静态代理、动态代理、拦截器思想
- Spring — AOP思想、AOP开发、Pointcut语法、注解配置AOP
- Spring — DAO层、Spring JDBC、Spring事务控制
- Spring — XML配置事务、注解+XML、纯注解的配置方式
- Spring整合MyBatis
- Spring Java Config — 组件注册相关注解
- Spring Java Config — 常用注解
跳转到目录
代码耦合严重
// DAO接口
public interface UserDao {
void getUser();
}
// DAO实现类
public class UserDaoMysqlImpl implements UserDao{
public void getUser() {
System.out.println("使用MySQL!");
}
}
public class UserDaoOracleImpl implements UserDao{
public void getUser() {
System.out.println("使用Oracle!");
}
}
// Service接口
public interface UserService {
void getUser();
}
// Service实现类
public class UserServiceImpl implements UserService{
// private UserDao dao = new UserDaoOracleImpl();
private UserDao dao = new UserDaoMysqlImpl();
public void getUser() {
dao.getUser();
}
}
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.getUser();
}
此时如果把UserDao
的实现类换成UserDaoOracleImpl ,此时就需要修改UserServiceImpl
的源代码, 不符合开闭原则!
开闭原则: 对扩展开放,对修改关闭;
跳转到目录
Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC
和持久层 Spring JDBC
以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架
什么是容器(Container): 从程序设计角度看就是封装对象的对象,因为存在放入、拿出等操作,所以容器还要管理对象的生命周期,如Tomcat就是Servlet和JSP的容器;
Spring 官网:https://spring.io/projects/spring-framework
下载地址: https://repo.spring.io/libs-release-local/org/springframework/spring/
跳转到目录
首先轻量级:不是指Spring框架的模块少,数量很轻,而是指Spring框架的非侵入性
,即对象可以不必依赖Spring的API类
其次,JavaEE开发可分成三层架构,针对JavaEE的三层结构,每一层Spring都提供了不同的解决技术。
Spring提供了JavaEE每一层的解决方案,所以也说Spring是JavaEE的全栈式(full stack)框架。
跳转到目录
方便解耦,简化开发。
Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理。
AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无须手动编程。
方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序。
方便集成各种优秀的框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2/Hibernate/MyBatis/Quartz等)的直接支持。
降低JavaEE API的使用难度
Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等)都提供了封装,使这些API应用难度大大降低。
核心容器由 spring-core,spring-beans,spring-context 和 spring-expression(SpEL,Spring表达式语言,Spring Expression Language)等模块组成,它们的细节如下:
spring-core
:提供了框架的基本组成部分,包括 IoC 和依赖注入功能。
spring-beans
:提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。
spring-context
:模块建立在由core和 beans 模块的基础上建立起来的,它以一种类似于JNDI注册的方式访问对象。Context模块继承自Bean模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过Servelet容器)等功能
spring-expression
:提供了强大的表达式语言,用于在运行时查询和操作对象图。它是JSP2.1规范中定义的统一表达式语言的扩展,支持set和get属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从Spring IoC容器检索对象,还支持列表的投影、选择以及聚合等。
原本在程序中手动创建对象的控制权
,交给Spring来管理;1、在没有IoC之前,我们的操作是: 若调用者需要使用某个对象,其自身就得负责该对象及该对象所依赖对象的创建和组装;
2、有IoC之后,调用者只管负责从Spring容器中获取需要使用的对象,不关心对象的创建过程,也不关心该对象依赖对象的创建以及依赖关系的组装;也就是把创建对象的控制权反转给了Spring框架.
DI: Dependency Injection(依赖注入)
从字面上分析:IoC :指将对象的创建权,反转给了Spring容器;DI : 指Spring创建对象的过程中,将对象依赖属性(常量,对象,集合)通过配置设值给该对象。
IoC从字面意思上很难体现出谁来维护对象之间的关系, Martin Fowler提出一个新的概念一- -DI ,更明确描述了“被注入对象 ( Service对象)依赖IoC容器来配置依赖对象( DAO对象)" .
跳转到目录
1、首先导入Maven坐标
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.2.2.RELEASEversion>
dependency>
2、HelloSpring类
import lombok.Data;
@Data
public class HelloSpring {
private String str;
private int age;
}
3、在resources中创建配置文件,命名为: applicationContext.xml
或beans.xml
都行
<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="helloSpring" class="com.sunny.domain.HelloSpring">
<property name="str" value="桂朝阳"/>
<property name="age" value="22"/>
bean>
beans>
4、测试类
public class HelloTest {
@Test
public void test2(){
HelloSpring helloSpring = null;
// 方式一: 官方推荐
// 获取ApplicationContext: 拿到Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
helloSpring = (HelloSpring) context.getBean("helloSpring");
// 方式二:
/*//1. 从classpath去找配置文件,创建资源对象
Resource resource = new ClassPathResource("applicationContext.xml");
//2. 根据资源对象,创建Spring IoC容器对象
BeanFactory factory = new XmlBeanFactory(resource);
//3. 从Spring IoC容器中获取指定名称(helloSpring)的对象
helloSpring = factory.getBean("helloSpring", HelloSpring.class);*/
System.out.println(helloSpring);
}
}
ClassPathXmlApplicationContext 默认加载classpath路径下的文件,只需指明对应文件的classpath路径下的配置文件名字即可。
FileSystemXmlApplicationContext : 该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。
WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
面向接口编程:返回 ApplicationContext (实际上ApplicationContext是一个接口), 即 Spring 的 IOC容器:
ConfigurableApplicationContext 子接口, 提供了一些方法 close(), refresh(), 可以让 ApplicationContext 刷新和关闭。
跳转到目录
上面代码写了两种创建Spring IoC容器的办法,下面介绍一下第二种;
XML-based configuration
Annotation-based configuration
Java-based configuration
跳转到目录
使用getBean方法,从容器中返回对象实例的三种方式:
签名1: Object getBean (String beanName);
// 根据bean对象在容器中的名称来获取
helloSpring = (HelloSpring) factory.getBean(“helloSpring”);
签名2:
// 按照指定的类型去寻找bean对象
helloSpring = factory.getBean(HelloSpring.class); // HelloSpring只能对应一个Bean,多个Bean的时候就会报错
签名3:
: 根据bean的类型 + ID 去寻找.
helloSpring = factory.getBean(“helloSpring2”, HelloSpring.class);
跳转到目录
当在Spring的配置文件 applicationContext.xml
中配置很多的bean
就会很不好管理.在开发中,随着应用规模越来愈大, 该文件中就变得特别臃肿; 为了提高可读性,我们可以将一个applicationContext.xml文件分解为多个配置文件,然后在applicationContext.xml中使用
来包含其他的配置文件即可!
语法
在applicationContext.xml
文件中导入
<import resource="classpath:xmls/helloSpring.xml"/>
然后helloSpring.xml
专门为了生成指定类对象的容器配置文件;
注意: 只有当框架实现了Resource接口才能够使用classpath前缀标识符
跳转到目录
<!--https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
2、基于junit4的测试
其中: @Autowired注解, 表示从Spring IoC容器中根据类型找到对应的bean,并自动注入到某个字段上
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunit4 {
// @Autowired:表示从Spring IoC容器中根据类型找到对应的bean,并自动注入到某个字段上
@Autowired
private Person person;
@Test
public void test(){
System.out.println(person);
}
3、基于junit5的测试
@SpringJUnitConfig
public class SpringJunit5{
@Autowired
private Person peroson;
@Test
void test1(){
System.out.println(person);
}
}
跳转到目录
public interface UserService {
void getUser();
}
public class UserServiceImpl implements UserService{
private UserDao dao;
// 利用set进行动态实现值的注入!
public void setUserDao(UserDao dao){
this.dao = dao;
}
public void getUser() {
dao.getUser();
}
}
public class MyTest {
public static void main(String[] args) {
// 创建Spring IoC容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("serviceImpl");
serviceImpl.getUser();
}
}