前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初始Spring 详解

初始Spring 详解

作者头像
Java_慈祥
发布2024-08-06 13:06:01
1040
发布2024-08-06 13:06:01
举报
文章被收录于专栏:SSM专栏

初始Spring 绿叶子

Spring框架: 轻量级框架, Java EE的春天,当前主流框架, Spring中:春天

  • Spring框架 致力于JavaEE 应用的各种 解决方案, 而不是仅仅专注于某一层的方案, 可以说Spring 是企业级应用开发"一站式"
  • (俗称一条龙服务)Spring针对不同的业务需求,都有不同的解决方案;
  • Spring 贯穿:表现层 业务层 持久层 然而,并不是要取代这些已有的框架,而是以高度的开放性与它们无缝整合; 企业级应用开发: 企业级应用:指为 商业组织 大型企业而创建部署的; 解决方案/应用 当前的企业级应用绝不可能是一个个 独立系统 , 一般都会部署多个进行交互的应用; 同时这些应用又都可能会与, 其它企业相关应用 连接. // 构成一个 结构复杂 跨越 Internet 的分布式企业应用 集群; 传统Java EE 解决企业级应用 使用 EJB:重量级,架构系统 而它:开发效率 , 开发难度 和 实际性能都令人失望. 所以后面出现了 Spring“救世主” 形式出现在了 Java程序员面前; EJB
  • EJB是的Enterprise Java Beans技术的简称, 又被称为企业Java Beans。基于分布式事务处理的企业级应用程序的组件
  • 但因为:学习比较难,开发难度大,依赖应用服务器,运用大量的设计模式 而被 淘汰;

内容IoC容器 , AOP实现 , 数据访问支持 , 简化 JDBC/ORM 框架 , 声明式事务 , Web集成... Spring 体系结构:

Spring一共有十几个组件:

  • Spring框架的核心组件只有三个:Core、Context和Beans。 他们构建起了整个Spring的骨骼架构,没有他们就不可能有AOP、Web等上层的特性功能。
  • AOP包(主要提供面向切面编程的实现)
  • Web(主要提供了Web应用开发的支持及针对Web应用的MVC思想实现)
  • ORM(为我们之前学的Hibernate,以及以后会学到的Mybatis这类持久化框架提供支持)
  • 还有Spring MVC(这个是它自带的一个web视图层,可以替代到Sturts2,将来我们还会详细的学习这个SpringMVC框架)…等等

Spring设计理念: Spring三个核心组件(Core、Context、Beans)。如果再再他们三个中选一个核心来,那就非Beans莫属了。 Spring是面向Bean(Java类)的编程:(BOP,Bean Oriented Programming) Bean在Spring 中作用就像Object(对象)对OOP(面向对象)的意义一样,没有对象的概念就没有面向对象编程,Spring中没有Bean也就没有Spring存在意义。就像一次演出舞台都准备好了但是却没有演员一样。 Spring解决了一个非常关键的问题,他可以让你把对象之间的关系转而使用配置文件来管理,也就是他的依赖注入机制,而这个注入关系在一个叫Ioc的容器中管理。Spring正是通过把对象包装在Bean中从而达到对这些对象管理以及一系列额外操作的目的。 那它是怎么管理这些Bean的呢? Spring把所有的Bean及它们之间的依赖关系以配置文件的方式组装起来,在一个叫IoC(Inversion of Control)的容器中进行管理,这也就是Spring的核心设计思想之一依赖注入机制,Spring的另一个核心设计思想叫做AOP ;

优点

  • 低侵入式设计:非入侵式设计,基于Spring开发的应用一般不依赖于Spring的类
  • Spring的依赖注入特性使Bean与Bean之间的依赖关系变的完全透明,可以统一管理和生成Bean,降低了耦合度:使用SpringIOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑
  • 它的面向切面编程aop 特性允许将一些通用任务如安全、事务、日志等进行集中式处理;
  • 独立于各种应用服务器,真正实现:一次编写,到处运行。
  • 并且它还提供了与第三方持久层框架的良好整合,并简化了底层数据库访问
  • 高度的开放性(可以和Struts2、Hibernate、MyBatis、CXF等很多主流第三方框架无缝整合)
  • 总的来说,Spring确实是一个令每个开发人员都值得学习的开发工具。接下来,我们就一起在学习过程中体会他的魅力吧。

Spring两大核心技术:

控制反转 (IoC:Inversion of Control ) /依赖注入(DI:Dependency Injection ) 面向切面编程 (AOP:Aspect Oriented Programming)

控制反转

概述:

由传统的代码实例化操作, 转换为由 Spring容器来操作处理 Bean的实例化操作; (依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。 也称 依赖注入 Dl 是面向对象的一种设计理念,用来减低程序代码之间的 耦合度;

什么是依赖:

代码语言:javascript
复制
// 值代码中, 通过局部变量, 方法参数, 返回值等.. 建立于对其它对象的调用关系; 
// 例如在:A类方法中 实例化 B类型的对象, 并调用其方法完成某种功能.. 就可以称为: `A类依赖于B类;
// 几乎所有应用程序,都是由两个及以上的类,通过彼此合作实现完整的功能 . 类于类之间的依赖关系, 增加了程序开发的复杂程度; 我们在开发一个/修改类的时候,还需要考虑使用该类的类 的影响;
is  是		子类继承父类 即 子类 is 父类;
has 包含	A类依赖B类	即 A类 has B类;

实例demo 以汽车为例子: 需要一个汽车类:Cart.Java

代码语言:javascript
复制
public class Cart {
	//这里车有两个属性:品牌 和 发动机; 因为车是依赖于发动机的所以 有一个发动机类型;
	//这里发动机是个接口类型,以表示多种发动机可选性; 
	public String brand;//品牌
	public Fdj fdj;//发动机
	//初始化
	public void init(){
		System.out.println("品牌:"+this.brand);
		//打印发动机;
		fdj.show(); 
	}
	//get/set方法;
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public Fdj getFdj() {
		return fdj;
	}
	public void setFdj(Fdj fdj) {
		this.fdj = fdj;
	}
}

发动机接口类:Fdj.Java

代码语言:javascript
复制
public interface Fdj {
	//打印当前发动机; 每一个继承发动机接口的 发动机子类都要实现改方法..
	public void show();
}

发动机接口实现类: BenTianFdj.Java本田发动机

代码语言:javascript
复制
public class BenTianFdj implements Fdj {

	@Override
	public void show() {
		// TODO Auto-generated method stub
		System.out.println("本田发动机");
	}

}

SanLingFdj.Java 三菱发动机

代码语言:javascript
复制
public class SanLingFdj implements Fdj {
	@Override
	public void show() {
		System.out.println("三菱发动机");
	}
}

实现类:Test.Java

代码语言:javascript
复制
public class Test {
	public static void main(String[] args) {
		Cart c = new Cart();
		//假设要  大众的品牌
		c.setBrand("大众");  
		//假设要 三菱发动机则;
		c.setFdj(new SanLingFdj());
		//最后结果;
		c.init();
	}
}

// 还记的以前写 Servlet 和 JSP 时候吗?三层:数据层 业务逻辑层 展示层 // 而有时候:实体类修改属性, 就要到数据层 —— 业务逻辑层 —— Service… 都要改; // 就像现在这样: Test是展示层 Cart是逻辑层… //发动机接口需要替换将导致 Cart —— Test发送改变; 而且现在 Test中还存在 new Cart…操作,导致程序的耦合… // 使程序, 程序不具备优良的**可扩展性 , 可维护性 ** 甚至在开发中将会 , 难以测试;

使用 工厂模式的方法解决此问题 // 加一个 工厂类:CartFactory.Java 专门用来制作Cart类 对象;

代码语言:javascript
复制
public class CartFactory {
	//制作汽车方法;
	public Cart createCart(String brand, String fdj) {
		Cart cart = new Cart();
		cart.setBrand(brand);
		if (fdj.equals("本田")) {
			BenTianFdj ben = new BenTianFdj();
			cart.setFdj(ben);
		} else if (fdj.equals("三菱")) {
			SanLingFdj san = new SanLingFdj();
			cart.setFdj(san);
		}
		return cart;
	}
}

// 修改Test.Java

代码语言:javascript
复制
public class Test {
	public static void main(String[] args) {
		//创建 汽车工厂;
		CartFactory cartFactory = new CartFactory();
		//生产汽车对象;
		Cart c = cartFactory.createCart("大众","三菱");
		//输出;
		c.init(); 
	}
}

// 这里 CartFactory 工厂类就是 “控制反转” 的思想; Test类中不在出现 new Cart(); 的操作; // 而是交给了 第三方 工厂来完成此操作; 在如何获取 所依赖的 Cart 对象的方式上, 控制权 发生了变化 反转 // 从原来的直接 new Cart(); 到 CartFactory 工厂 .cartFactory(); 这就是 控制反转 降低了 耦合,但还是有 new Cart(); 操作并不是真正的解决 耦合; // 大量的工厂 引入开发过程中,会导致 工作量增加… // Spring 解决了这个问题, 提供了完整的 IOC 实现控制反转 , 使开发可以专注于 业务类等操作;

使用Spring 修改:

配置Spring


官网上下载: 所需要的Spring资源,Spring Framework

对于一些开发工具其实都已经集成了:开发环境(MyElicpse) : 在web项目上 ——右击项目——选择MyElicpse项——project facets [capabilities] 项—— 在选择:Install Spring Facet 一个小绿叶标志哦~选中即可!

自动导入对应的 Jar 包 Src下产生对应的 applicationContext.xml :(Spring 的配置文件,进行依赖注入DI) 可以在Src 下专门建一个Source FoIderle文件 resources 名 资源目录; 所有的资源文件都可以放在这儿; Myelicpse 中就相当于就是在Src 下的一样, 不会有任何影响;

需要Jar Spring运行依赖:commons-logging-1.1.1.jar 为了方便观察,Bean实例化,采用 lo4j 输出查看log4j-1.2.17.jar 需要对应的 log4j.properties

Spring 的配置文件 applicationContext.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	
	
	<!-- Spring使用<Bean />标签:进行依赖注入 完成控制反转,实例化类操作; 
		属性:
			id:			值唯一, 表示定义Bean实例的名称;
			class:		表示定义Bean实例的类型; 值就是表示类的: 引用类路径; 
						Myelicpse: 还可以观察类文件图标有没有出现S 来确定类是否被 Spring容器管理!
		子元素:
			<property name="Bean的属性名" />	
				<value>基本数据类型,直接赋值</value> 
							或 
				<ref bean="复杂数据类型Bean,直接引用其ID 即可(就相当于new一样)" >												
			</property>		
			
	 			
	 -->	
	<!-- 因为本田/三菱类并没有属性,所以就这样就完了... -->
	<bean id="BT" class="com.wsm.spring.BenTianFdj" ></bean> <!-- 本田发动机 -->
	<bean id="SL" class="com.wsm.spring.SanLingFdj" ></bean> <!-- 三菱发动机 -->
	
	<bean id="cart" class="com.wsm.spring.Cart" >
		<property name="brand" value="大众"  />	 <!-- 给基本类型属性brand 直接赋值 -->
		<property name="fdj"   ref="BT"   	 />  <!-- 给复杂类型属性fdj   引用其bean id赋值 -->
		<!-- 
			注意:这里表面上是 根据属性名赋值,实际上内部是调用了属性的 setxx(); 被称为 "设值注入"
				  所以一定要注意JavaBean命名规范,而且  如果没 get/set 则会编译报错...
			eg:   如果 name="name" 则底层调用 setName();  aa 则 setAa();...
		 -->	
	</bean>
	
	
</beans>

Test.Java

代码语言:javascript
复制
package com.wsm.spring;

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

public class Test {
	public static void main(String[] args) {
		//通过 ClassPathXmlApplicationContext 实例化 Spring 上下文;
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		//通过 ApplicationContext 的getBean("Bean的Id"); 获取对应的Bean 的实例,返回Object类型;
		Cart c = (Cart)context.getBean("cart"); //强转为 Cart类型对象;
		//调用方法;
		c.init();
	}
	/*
	 * ApplicationContext 是一个接口,负责读取Spring 配置文件;
	 * 		管理对象加载,维护Bean对象与Bean对象之间的依赖关系; 负责Bean的生命周期; 
	 * ClassPathXmlApplicationContext 是 ApplicationContext 的实现类:
	 * 		从 classpath路径读取Spring配置文件;
	 * */
	 
}	
面向切面编程 (AOP:Aspect Oriented Programming)

上图:这个代码非常熟悉把,就是基本的业务实现的代码; 日志——异常处理——事务控制 都是一个健壮的业务系统所必须的。 为了保证系统健壮性可用,就要在众多业务方法中反复编写类似的代码; 使原本复杂的代码更加复杂; 业务功能的开发者还要关注这些 “额外” 的代码是否处理正确, 遗漏的地方; 如果修改增加新的功能,也可能会导致 业务代码的修改; 对这些, 零散的代码, 穿插在业务中的代码操作就是 "横切逻辑" 也称为 切面 为了不受干涉的专注于 业务的代码,将这些代码 抽离 出来,放在专门的 方法/类中; 便于管理 维护 ,但依然无法彻底的完成 业务 和 切面逻辑 的彻底解耦 业务的代码中还要保留调用的 方法();代码 这正是 AOP 解决的问题: 面向切面编程,简单的说就是: 在不改变原来程序基础上为,代码增加新的功能,对代码进行增强处理. 设计思想来源于 :代理模式(看样子后面得看看设计模式了) 原理: 将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决 采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能

AOP基本概念

  • 切面(Aspect) 切面可以理解为:切点和增强组成切面。它包括了横切逻辑的定义,也包括了连接点的定义。
  • 切入点(Pointcut) 对连接点. 特征进行描述; 可以使用正则表达式 简单的说,就是连接点的查询条件
  • 连接点(Join Point) 程序执行过程中某个具体执行的点 ( 就是核心要执行的方法; )
  • 增强处理(Advice) 增强处理又分为: 前置增强,后置增强,环绕增强,异常抛出增强,最终增强等类型; 是织入到目标类连接点上的一段程序代码。 增强包含了用于添加到目标连接点上的一段执行逻辑,又包含了用于定位连接点的方位信息。
  • AOP代理(AOP proxy) AOP框架创建的对象。一个类被AOP织入增强之后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。(代理对象)
  • 目标对象(Target object) 增强逻辑 织入的目标类;就是被增强的类的对象;
  • 织入(Weaving) 将增强添加到目标类具体连接点上的过程。 AOP有三种织入的方式:编译期织入、类装载期织入、动态代理织入(spring采用动态代理织入) Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中

总结: 在AOP中切面就是与业务逻辑独立,但又垂直存在于业务逻辑的代码结构中的 通用功能组合 切面与业务逻辑相交的点就是切点; 连接点就是把业务逻辑 离散化后的关键节点;即 核心的业务逻辑代码块方法(); 连接点属于切点,是所有切入点的子集; 增强(Advice)就是切面在切点上要执行的功能增加的具体操作; 将增强添加到目标类具体连接点上的过程。这个就叫`织入

//当然空讲理论当然不是关键, 奉上代码 -"_"- : // 在上述代码中扩展: 新增一个类:Aop.Java 可以理解为: 增强处理类, 里面存储增强代码方法();

代码语言:javascript
复制
public class Aop {
	private Logger log = Logger.getLogger(Aop.class);
	
	//前置增强			//连接点对象
	public void beforeee(JoinPoint joinPoint){
		log.info("前置,调用" + joinPoint.getTarget() + "类,下的方法是"
				+ joinPoint.getSignature().getName() + ",方法的参数是:"
				+ Arrays.toString(joinPoint.getArgs()));
	}
	//后置增强				//连接点对象,返回值
	public void afterReting(JoinPoint joinPoint,Object result){  
		log.info("后置,调用" + joinPoint.getTarget() + "类,下的方法是"
				+ joinPoint.getSignature().getName() + ",方法的参数是:"
				+ Arrays.toString(joinPoint.getArgs()) + ",方法的返回值是:" + result);
	}
	/*
	JoinPoint 连接点对象;
	为了能够在增强方法中获得当前连接点的信息,以便实施相关的判断和处理,
	可以在增强方法中声明一个JoinPoint类型的参数。
	Spring会自动注入实现该实例。
	通过该实例的getTarget( )    方法可以得到被代理的目标对象,!!!
	getSignature( )方法返回被代理的目标方法,
	getArgs( )方法返回传递给目标方法的参数数组。
	对于实现后置增强的afterReturning( )方法,还可以定义一个参数用于接收目标方法的返回值。
	*/
}

Spring 的配置文件 applicationContext.xml 将增强处理和切入点结合在一起,在切入点处插入增强处理,完成"织入" 另外在这之前还需要导入aop需要的命名空间 Myelicpse可直接在文件格式下选中——Namespaces——打勾

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"   
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	<!-- 引入命名空间:xmlns:aop="http://www.springframework.org/schema/aop" -->
	<!-- 省略了之前的代码..注意哦 -->
	
	<!-- <aop:config>中完成织入 -->
	<aop:config>
		<aop:pointcut expression="execution (public String init())" id="mypoint"/>
		<!--
			配置切入点的标签<aop:pointcut>
			<aop:pointcut>的expression属性可以配置切入点表达式:切入点表达式支持模糊匹配,讲解几种常用的模糊匹配:
				public * addNewUser(entity.User)  	 “*”表示匹配所有类型的返回值。
				public void *(entity.User)		“*”表示匹配所有方法名。
				public void addNewUser(..)		“..”表示匹配所有参数个数和类型。
				* com.service.*.*(..)			匹配com.service包下所有类的所有方法。
				* com.service..*.*(..)		匹配com.service包及其子包下所有类的所有方法
				....等等;  Myelicpse工具也可以根据,一些小箭头 
		-->
		<aop:aspect ref="myLogAop">  <!-- aspect:切面,切入点和增强组成..  ref:引入增强处理类,类对象 -->
			<!-- 前置增强:      前置的方法名();	        切入点                               -->
			<aop:before method="beforeee" pointcut-ref="mypoint"/>
			 <!-- 后置增强:                后置方法名();				  切入点           返回值参数名; -->
			 <aop:after-returning method="afterReting" 	pointcut-ref="mypoint"	 returning="result"/> 
		</aop:aspect>
	
	</aop:config>
	
	<!-- 增强处理类 -->
	<bean id="myLogAop"  class="com.wsm.aop.Aop"></bean> 

</beans>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始Spring 绿叶子
  • Spring两大核心技术:
    • 控制反转
      • 使用Spring 修改:
        • 面向切面编程 (AOP:Aspect Oriented Programming)
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档