Spring框架深度揭秘:掌握现代Java开发必备技能

Spring概述

1.什么是Spring

Spring 是分层的、JavaSE/EE 一站式(full-stack)、轻量级开源框架。

JavaEE 分层

JavaEE 规范的三层结构体系:

表现层(页面数据显示、页面跳转调度),例如 jsp/servlet

业务层(业务处理和功能逻辑、事务控制),例如 service

持久层(数据存取和封装、和数据库打交道),例如 dao

image-20230403215720330

Spring 提供了 JavaEE 各层的解决方案:

表现层:struts1、struts2、Spring MVC

业务层:Ioc、AOP、事务控制

持久层:JdbcTemplate、HibernateTemplate、ORM 框架(对象关系映射)整合

2.Spring 的体系结构

Spring 框架是一个分层架构,它包含一系列的功能要素并被分为大于 20 个模块。这些模块分为 Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation 和测试部分,如图:

image-20230403220826010

核心容器(Core Container) 包括 Core、Beans、Context、EL 模块。

1:Core 和 Beans 模块提供了 Spring 最基础的功能,提供 IoC 和依赖注入特性。这里的基础概念是 BeanFactory,它提供对 Factory 模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。

2:Context 模块基于 Core 和 Beans 来构建,它提供了用一种框架风格的方式来访问对象,有些像 JNDI 注册表。Context 封装包继承了 beans 包的功能,还增加了国际化(I18N),事件传播,资源装载,以及透明创建上下文,例如通过 servlet 容器,以及对大量 JavaEE特性的支持,如 EJB、JMX。核心接口是 ApplicationContext。

3:Expression Language,表达式语言模块,提供了在运行期间查询和操作对象图的强大能力。支持访问和修改属性值,方法调用,支持访问及修改数组、容器和索引器,命名变量,支持算数和逻辑运算,支持从 Spring 容器获取 Bean,它也支持列表投影、选择和一

般的列表聚合等。

数据访问集成部分(Data Access/Integration)

1:JDBC 模块,提供对 JDBC 的抽象,它可消除冗长的 JDBC 编码和解析数据库厂商特有的错误代码。

2:ORM 模块,提供了常用的"对象/关系"映射 APIs 的集成层。 其中包括 JPA、JDO、Hibernate 和 iBatis 。利用 ORM 封装包,可以混合使用所有 Spring 提供的特性进行"对象/关系"映射,如简单声明性 事务管理 。

3:OXM 模块,提供一个支持 Object 和 XML 进行映射的抽象层,其中包括 JAXB、Castor、XMLBeans、JiBX 和 XStream。

4:JMS 模块,提供一套"消息生产者、消费者"模板用于更加简单的使用 JMS,JMS 用于用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

5:Transaction 模块,支持程序通过简单声明性 事务管理,只要是 Spring 管理对象都能得到 Spring 管理事务的好处,即使是 POJO,也可以为他们提供事务。

Web

1:Web 模块,提供了基础的 web 功能。例如多文件上传、集成 IoC 容器、远程过程访问、以及 Web Service 支持,并提供一个 RestTemplate 类来提供方便的 Restful services访问

2:Web-Servlet 模块,提供了 Web 应用的 Model-View-Controller(MVC)实现。Spring MVC 框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的 JSP 标签,完全无缝与 Spring 其他技术协作。

3:Web-Struts 模块, 提供了对 Struts 集成的支持,这个功能在 Spring3.0 里面已经不推荐了,建议你迁移应用到使用 Struts2.0 或 Spring 的 MVC。

4:Web-Portlet 模块,提供了在 Portlet 环境下的 MVC 实现

AOP

1:AOP 模块,提供了符合 AOP 联盟规范的面向方面的编程实现,让你可以定义如方法拦截器和切入点,从逻辑上讲,可以减弱代码的功能耦合,清晰的被分离开。而且,利用源码级的元数据功能,还可以将各种行为信息合并到你的代码中 。

2:Aspects 模块,提供了对 AspectJ 的集成。

3:Instrumentation 模块, 提供一些类级的工具支持和 ClassLoader 级的实现,可以在一些特定的应用服务器中使用。

Test

1:Test 模块,提供对使用 JUnit 和 TestNG 来测试 Spring 组件的支持,它提供一致的ApplicationContexts 并缓存这些上下文,它还能提供一些 mock 对象,使得你可以独立的测试代码。

3 .Spring的核心

IoC(Inverse of Control 控制反转): 将对象创建权利交给 Spring 工厂进行管理。

AOP(Aspect Oriented Programming 面向切面编程),基于动态代理的功能增强方式。

Spring 是基于 IOC 和 AOP 的一套编程框架。

4. Spring的优点

Spring 出现为了解决 JavaEE 实际问题

(1)方便解耦,简化开发Spring 就是一个大工厂,可以将所有对象创建和依赖关系维护,交给 Spring 管理

(2)AOP 编程的支持Spring 提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

(3)声明式事务的支持只需要通过配置就可以完成对事务的管理,而无需手动编程

(3)方便程序的测试Spring 对 Junit4 支持,可以通过注解方便的测试 Spring 程序

(5)方便集成各种优秀框架Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz、webservice、activity 等)的直接支持

(6)降低 JavaEE API 的使用难度Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些 API 应用难度大大降低

Spring IoC快速入门

Spring 核心内容的基本开发步骤:下载开发包,导入 jar 包 编写代码(基础代码和调用代码) 编写配置文件(XML) 测试

1.Spring 的开发包

开发包的下载 Spring 官方:http://spring.io/

下载网址:http://repo.spring.io/libs-release-local/org/springframework/spring/

我们采用的版本是:4.2.x 的版本(企业主流版本,框架整合也需要对应版本 jar):

Spring4.2 版本开发包目录结构:

image-20230403221919841

2.开发环境测试搭建

1.Spring 项目的核心容器的最基本 Jar 包(4 个):

image-20230403222136769

2.Spring 框架所需的日志包(2 个,依赖 jar 库中找):默认采用 apache commons-logging(JCL)日志框架+log4j 的日志实现,还需要添加 log4j 的配置文件。

添加 log4j 的日志文件:添加 log4j.properties 文件放置到 src 下。

### direct log messages to stdout ###  控制台
显示控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
输出错误
log4j.appender.stdout.Target=System.err
显示风格
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
自定义的风格
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###  文集
log4j.appender.file=org.apache.log4j.FileAppender
文件记录
log4j.appender.file.File=c\:mylog.log  
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###
选择日志显示格式
log4j.rootLogger=info  级别, stdout  输出控制台/文件 

IoC控制反转的实现

IoC 底层实现:工厂(设计模式)+反射(机制) + 配置文件(xml)。

1 Spring核心配置文件的编写

IoC 控制反转的理解和实现

在 src 下建立 applicationContext.xml (位置:applicationContext.xml 文件放置到任何目录都可以,习惯上放在 src 目录或者 WEB-INF 目录)

<?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:是Spring工厂帮你new的一个对象(机制:反射机制)-->
<!--    class:new的对象类型的字符串的表现形式,全类名-->
<!--    id/name:标识对象的名字,用来获取bean对象的表示,习惯上这个名字为接口的名字,首字母小写-->
    <bean name="userDao" class="cn.tedu.UserDaoImpl"></bean>


<!--   DI 依赖注入
       双方都必须是Bean 在创建Service的时候,主动将dao的以来对象交给Service
-->
    <bean name="userService" class="cn.tedu.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>
</beans>
package cn.tedu;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceImpl implements IUserService{
    @Override
    public void login() {
        System.out.println("UserServiceImpl 被调用了");
        //IUserDao userDao=new UserDaoImpl();
        //Spring的配置方式new对象,IOC控制反转
        //读取applicationContext.xml文件,获取Bean节点
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        //根据id获取bean
        IUserDao userDao= (IUserDao) ac.getBean("userDao");
        userDao.findByUserNameAndPassword();
    }

}

service spring 的配置方式,IOC 控制反转

public class UserServiceImpl implements IUserService{

		public void login() {
			System.out.println("UserServiceImpl-service 层被调用了。。。");
			//spring 的配置方式,IOC 控制反转
			//构建一个 spring 的工厂,使用 applicationContext.xml(spring 的核心配
			置文件)获取对象
			ApplicationContext ac = new
					ClassPathXmlApplicationContext("applicationContext.xml");
			//从 spring 工厂中使用对象的标识获取对象
			IUserDao userDao = (IUserDao) ac.getBean("userDao");
			userDao.findByUsernameAndPassword();
		}
	}

2.Spring的工厂

ApplicationContext 直译为应用上下文,是用来加载 Spring 框架配置文件,来构建 Spring 的工厂对象,它也称之为 Spring 容器的上下文对象,也称之为 Spring 的容器。

ApplicationContext 只是 BeanFactory(Bean 工厂,Bean 就是一个 java 对象) 一个子接口

image-20230404121800802

3.Spring工厂的直接获取(两种方式)-了解

方法一:从classpath 路径加载

在类路径下寻找配置文件来实例化容器ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[{“applicationContext.xml”});

可以在整个类路径中寻找 xml 文件

通过这种方式加载。需要将 spring 的配置文件放到当前项目的 classpath 路径下 classpath 路径指的是当前项目的 src 目录,该目录是 java 源文件的存放位置。

方法二:从磁盘路径加载

在文件系统路径下寻找配置文件来实例化容器

ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\applicationContext.xml”});

(1)Spring 的配置文件可以指定多个,可以通过 String 数组传入。

(2)通过 getBean 方法获得 Spring 容器管理 Bean 对象

Bean 获取的两种方式

/**1:使用 spring 容器中的标识获取对象*/
 ApplicationContext applicationContext = newClassPathXmlApplicationContext("applicationContext.xml"); 
 //IUserService userService=(IUserService) applicationContext.getBean("userService");

/**
 * 2:根据 bean 的类型来获取:自动到 spring 容器中查找哪个 bean 是这个类型
 * 如果 Object instanceOf(IUserService.class)或者 Object 
instanceOf(UserServiceImpl.class)
 * 类型获取有个郁闷的情况:如果容器中有两个同样的类型,则会报错!!!!!
 */
 //IUserService userService=(IUserService) 
applicationContext.getBean(IUserService.class);
IUserService userService=(IUserService) applicationContext.getBean(UserServiceImpl.class);//一般不会使用实现类
 //业务方法
 userService.login();

常用根据名称获取(id/name),即第一种方式,使用 spring 容器中的标识获取对象

4.IoC容器装配Bean_基于XML配置方式

实例化 Bean 的四种方式 (了解)

Bean1

package com.igeek;
public class Bean1 {
	public Bean1() {
		System.out.println("Bean1 ...");
	}
}

applicationContext.xml 配置bean

<bean id="bena1" class="com.igeek.Bean1"></bean>

配置方法

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Bean1 bean1=ac.getBean("Bean1");
System.out.println(bean1);

5.Bean的作用域

由 spring 创建的 bean 对象在什么情况下有效

image-20230404124738744

项目开发中通常会使用:singleton 单例、 prototype 多例

Singleton: 在一个 spring 容器中,对象只有一个实例。(默认值)

Prototype: 在一个 spring 容器中,存在多个实例,每次 getBean 返回一个新的实例。

6. Bean的生命周期

通过 spring 工厂,可以控制 bean 的生命周期。

applicationContext.xml

<!-- 生命周期调用的两个方法
init-method:初始化时(后)调用的,bean 中的共有方法即可
destroy-method:销毁时(前)被调用的。
-->
<bean id="lifeCycleBean" class="com.igeek.xmllifecycle.LifeCycleBean"
init-method="init" destroy-method="destroy" scope="singleton"/>

SpringTest.java

@Test
public void test(){ 
 //先获取 spring 的容器,工厂,上下文
 ApplicationContext applicationContext = newClassPathXmlApplicationContext("applicationContext.xml"); 
 //对于单例此时已经被初始化
 //获取 bean
 LifeCycleBean lifeCycleBean=(LifeCycleBean) applicationContext.getBean("lifeCycleBean"); 
 System.out.println(lifeCycleBean); 
 lifeCycleBean.save(); 
 //为什么没有销毁方法调用。
 //原因是:使用 debug 模式 jvm 直接就关了,spring 容器还没有来得及销毁对象。
 //解决:手动关闭销毁 spring 容器,自动销毁单例的对象
 ((ClassPathXmlApplicationContext)applicationContext).close();
 
 }

原因:销毁方法的执行必须满足两个条件:

1) 单例(singleton)的 bean 才会可以手动销毁。

2) 必须手动关闭容器(调用 close 的方法)时,才会执行手动销毁的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值