企业级应用开发(SSM) Spring

article/2025/10/30 14:51:44

目录

一:引言

1.1企业级系统:

1.2那么如何去应对企业级应用开发

 1.3 Spring的绿草丛

 二:Spring的绿草丛

2.1 Spring 介绍

 2.2   Spring两大核心技术

        a.控制反转(IoC(Inversion of Control) / 依赖注入(DI))

        b.面向切面编程(AoP)

2.3 Spring 优点

2.4 Spring工程构建

2.4.1Maven Spring依赖

2.4.2 Spring核心配置文件编写

2.4.3 完成控制反转及依赖注入的实例

2.4.4 Spring中的IoC产生的对象是否是单例模式 (是)

2.4.5延迟实例化

2.5 Bean的三种实例化方式

2.5.1构造方法方式【重点】  

2.5.2静态工厂方式(了解) 

2.5.3实例工厂方式(了解)

2.6 Bean的生命周期

2.7 Bean的销毁时机

三:应用XML编程实现AOP

3.1AOP的代理实现形式(一共有三种)

3.1.1 通过JDK动态代理实现

 优点

术语概念

 3.1.2通过CGLib动态代理实现

3.1.3 AOP术语

3.2 通过编程形式基于XML实现AOP

3.2 AOP使用场景



一:引言

1.1企业级系统:

  •         大规模:用户数量多,数据规模大,功能众多
  •         性能和安全要求高。
  •         业务复杂
  •         灵活多变(指的是用户的需求)

1.2那么如何去应对企业级应用开发

 1.3 Spring的绿草丛

Spring : 轻量级框架(相比于EJB),JavaEE的春天,当前主流框架。

目标:使现有技术更加易用,实现代码最佳实践。

内容:IoC容器 ,AoP实现(俩大核心内容)

        数据访问支持(简化JDBC/ORM框架 ,声明式事务)

        web集成(核心框架SpringMVC)

 二:Spring的绿草丛

2.1 Spring 介绍

Spring 是一个企业级应用框架。其中包含了大量的各种应用组件。 Spring 框架为现代基于 Java 的企业应用程序提供了一个全面的编程和配置模型,能够在任何类型的部署平台上进行部署。其核心是 IoC AOP 设计理念是面向Bean编程

 2.2   Spring两大核心技术

        a.控制反转(IoC(Inversion of Control) / 依赖注入(DI))

                控制反转(Inversion of Control),将原来有我们来完成的实例化过程,交给容器来完成。将组件对象的控制权从代码本身转移到外部容器。

                依赖注入。依赖于某一种媒介完成对某一个对象的初始化或者是赋值。

        b.面向切面编程(AoP)

                面向切面编程(Aspect Oriented Programming)

2.3 Spring 优点

  1. 低侵入式设计
  2. 独立于各种应用服务器
  3. 依赖注入特性将组件关系透明化,降低了耦合度
  4. 面向切面编程特性允许将通用任务进行集中式处理
  5. 与第三方框架的良好整合

2.4 Spring工程构建

2.4.1Maven Spring依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.22</version>
</dependency>

2.4.2 Spring核心配置文件编写

<?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"></beans>

2.4.3 完成控制反转及依赖注入的实例

<!-- 控制反转 -->
< bean id = "userInfo" class = "com.domain.UserInfo" >
</ bean >
<!-- 完成依赖注入 DI -->
< property name = "username" value = " 张三 " />
< property name = "content" value = " 刘家豪大笨蛋! " />
<bean id="userInfo" class="com.domain.UserInfo">
        <!--完成依赖注入 DI-->
        <property name="username" value="张三 " />
        <property name="content" value="刘家豪大笨蛋! " />
</bean>

 beanid名称,在同一个配置文件下,是只能拥有一个,不能够出现重复的id名称!如果出现相同的id,则会报如下错误:

测试:

@Test
public void testInit () {
// 步骤 1 :获取到 ApplicationContext 对象
//ClassPathXmlApplicationContext: 代表从类路径下加载 xml 配置文件,返回
ApplicationContext 的对象
ApplicationContext ctx = new ClassPathXmlApplicationContext ( "applicationContext.xml" ) ;
// 步骤 2 :从 ApplicationContext 容器中获取到 userInfo 的对象
UserInfo userInfo = ( UserInfo ) ctx . getBean ( "userInfo" ) ;
userInfo . say ();
}

2.4.4 Spring中的IoC产生的对象是否是单例模式 (是)

scope 属性代表设置当前当前 bean 的作用域。
        singleton:单例
        prototype:每次调用时都会创建一个新的对象。
<bean name = "helloSpring" class = "com.csi.bean.HelloSpring" scope = "singleton" >
        <!--DI-->
        <property name = "hello" value = " 今天天气好晴朗 " />
</bean>
//ClassPathXmlApplicationContext: 代表从类路径下加载 xml 配置文件,返回 ApplicationContext
的对象
ApplicationContext ctx = new ClassPathXmlApplicationContext ( "applicationContext.xml" ) ;
// 步骤 2 :从 ApplicationContext 容器中获取到 userInfo 的对象
UserInfo userInfo = ( UserInfo ) ctx . getBean ( "userInfo1" ) ;
userInfo . say ();
System.out.println(userInfo);
userInfo = ( UserInfo ) ctx . getBean ( "userInfo1" ) ;
userInfo . say ();
System.out.println(userInfo);

以上代码,对同一个 bean 进行两次调用,得到对象是同一个对象,说明在 Spring 的设计当中,所使用的是单例设计模式!每一个调用的 bean ,都会生成一个新的对象。

2.4.5延迟实例化

< bean id = "userInfo1" class = "com.domain.UserInfo" >
        <!-- 完成依赖注入 DI -->
        < property name = "username" value = " 张三 " />
        < property name = "content" value = " 刘家豪大笨蛋! " />
</ bean >
< bean id = "userInfo2" class = "com.domain.UserInfo" >
        <!-- 完成依赖注入 DI -->
        < property name = "username" value = " 李四 " />
        < property name = "content" value = " 翟雪松大帅哥! " />
</ bean >

        虽然都是对同一个类进行实例化,但是每一个bean就代表着一个对象。

         当Spring加载配置文件时,默认情况下,就会将所有配置的bean全部实例化。
         如果在Spring的bean节点中,配置了lazy-init的属性,就会实现延迟初始化的效果,即在spring容器启动时,并不会立刻初始化该对象,直到获取该对象的id或者是name时,才会初始化对象。

<bean name = "helloSpring" class = "com.csi.bean.HelloSpring" scope = "singleton"
lazy-init = "true" >
        <!--DI-->
        <property name = "hello" value = " 今天天气好晴朗 " />
</bean>
// 需要先加载 Spring 核心配置文件 , 如果设置了 lazy-init ,调用该语句时不会初始化对象
ApplicationContext ctx = new ClassPathXmlApplicationContext ( "applicationContext.xml" ) ;
// 调用时才会初始化对象
HelloSpring helloSpring = ( HelloSpring ) ctx . getBean ( "helloSpring" );

2.5 Bean的三种实例化方式

2.5.1构造方法方式【重点】  

  • BookDaoImpl实现类
public class BookDaoImpl implements BookDao {
        public BookDaoImpl () {
                System . out . println ( "book dao constructor is running ...." );
        }
        public void save () {
                System . out . println ( "book dao save ..." );
        }
}

  

  • applicationContext.xml配置
<!-- 方式一:构造方法实例化 bean-->
<bean id = "bookDao" class = "com.csi.dao.impl.BookDaoImpl" />
  • AppForInstanceBook测试类

public class AppForInstanceBook {
        public static void main ( String [] args ) {
                ApplicationContext ctx = new
                ClassPathXmlApplicationContext ( "applicationContext.xml" );
                BookDao bookDao = ( BookDao ) ctx . getBean ( "bookDao" );
                bookDao . save ();
        }
}

2.5.2静态工厂方式(了解) 

  • orderDao接口和orderDaoImpl实现类
public interface OrderDao {
        public void save ();
        }
public class OrderDaoImpl implements OrderDao {
        public void save () {
                System . out . println ( "order dao save ..." );
        }
}
  • OrderDaoFatory工厂类
// 静态工厂创建对象
public class OrderDaoFactory {
public static OrderDao getOrderDao (){
        System . out . println ( "factory setup...." );
        return new OrderDaoImpl ();
        }
}
  • applicationContext.xml配置
<!-- 方式二:使用静态工厂实例化 bean-->
<bean id = "orderDao" class = "com.csi.factory.OrderDaoFactory" factory
method = "getOrderDao" />
  • AppForInstanceOrder测试类
public class AppForInstanceOrder {
public static void main ( String [] args ) {
ApplicationContext ctx = new ClassPathXmlApplicationContext ( "applicationContext.xml" );
        OrderDao orderDao = ( OrderDao ) ctx . getBean ( "orderDao" );
        orderDao . save ();
        }
}

2.5.3实例工厂方式(了解)

  • UserDao接口和UserImpl实现类

  • UserDaoFactory工厂类

  • applicationContext.xml配置

  • AppForInstanceUser测试类

2.6 Bean的生命周期

  • 使用init-methoddestroy-method

测试类(使用实现类类型,接口类型没有close方法)

  • 实现InitializingBean, DisposableBean接口

        心得:如果既实现了这俩个接口,又手写了初始化和销毁方法。经过测试得知,实现接口的初始化和注销方法优先执行。

2.7 Bean的销毁时机

  • 容器关闭前触发bean的销毁
  • 关闭容器方式:
        手工关闭容器
                        ConfigurableApplicationContext 接口 close() 操作
        注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
                        ConfigurableApplicationContext 接口 registerShutdownHook() 操作 。
关闭钩子比较合情,当调用后不会立即关闭,方法执行完毕后才进行关闭。

三:应用XML编程实现AOP

        面向切面编程(Aspect Oriented Programming) 。其目的是为了拦截某些类下的某些方法、参数、返回值内容。在此基础之上,通过增强形式,使用 代理设计模式 显示 AOP 编程。

3.1AOP的代理实现形式(一共有三种)

3.1.1 通过JDK动态代理实现

        动态代理是指:代理类对象是在运行时,由JVM 根据反射机制动态生成的。动态代理不需要定义代理类的 .java源文件。动态代理其实就是 JDK 运行期间,动态创建 class 字节码文件并加载到 JVM。

 优点

  1.  不用创建类文件
  2.  当修改了接口中的方法时,不会影响代理类
  3.  不用给不同的目标随时创建代理

术语概念

  1. 1目标类:实现了功能接口的实现类对象
  2. 代理类:作为调用类和目标类之间的桥接
  3. 调用类:需要调用目标类方法来完成值的获取
  4. OCP原则:程序设计的一个考虑,类设计的时候尽量避免方法当中代码的二次修改,但是欢迎类设计者扩展一个类的功能(方法)
  5.  耦合度:一个类过于依赖于另一个类,就会产生耦合性

注意:JDK的动态代理,是要求必须拥有接口的。Spring能够对任何的一个对象都进行代理设计,此时如果某个对象没有对应的接口,只是单单的利用JDK动态代理,则无法创建对应的代理对象。Spring AOP就会采CGLib生成。

例子:

 3.1.2通过CGLib动态代理实现

        CGLib是通过继承目标类实现的一种代理方式,因此不需要提前准备目标对应的接口。在 Spring 生成代理对象时,实际上是生成代理目标的一个子类。

3.1.3 AOP术语

  • 连接点(JoinPoint):正在执行的方法,例如:update()delete()select()等都是连接点。 每个方法不仅仅只有一个连接点,方法前中后都可能成为一个连接点。
  • 切入点(Pointcut):进行功能增强了的方法,例如:update()delete()方法,select()方法没有被增强所以不是切入点,但是是连接点。

  • 通知(Advice):在切入点前后执行的操作,也就是增强的共性功能

                在SpringAOP中,功能最终以方法的形式呈现

  • 通知类:通知方法所在的类叫做通知类
  • 切面(Aspect):描述通知切入点的对应关系,也就是哪些通知方法对应哪些切入点方法。

3.2 通过编程形式基于XML实现AOP

  • 引入aspectjwarver环境
        <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version></dependency>
  • 修改核心配置文件

  • 编写增强通知类
package com.csi.proxy;import org.aopalliance.intercept.Joinpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;import java.util.Arrays;public class LogManagerAdvice {//构造public LogManagerAdvice(){System.out.println("建立数据库连接.....");}//前置增强public void before(JoinPoint joinpoint){System.out.println("被增强的类:"+joinpoint.getTarget().getClass().getName()+ "被拦截的方法:" +joinpoint.getSignature().getName()+"参数是:"+ Arrays.toString(joinpoint.getArgs()));System.out.println("开始记录日志。。。。");}//后置增强public void afterReturning(JoinPoint joinPoint ,Object o){System.out.println("结束日志记录。。。");}//异常通知public void afterThrowing(JoinPoint joinPoint,RuntimeException e){System.out.println(joinPoint.getTarget()+"的"+joinPoint.getSignature().getName()+",报出的信息是:"+e);}//最终通知public void after(JoinPoint joinPoint){System.out.println("最终通知:"+joinPoint.getTarget()+"的"+joinPoint.getSignature().getName()+",参数是"+Arrays.toString(joinPoint.getArgs()));}//环绕通知public void afterAround(ProceedingJoinPoint pjp){System.out.println("开启事务.....");try {Object result = pjp.proceed();System.out.println("事务提交....");} catch (Throwable e) {e.printStackTrace();System.out.println("事务回滚....");}finally {System.out.println("释放SqlSession对象");}}
}
  • 在核心配置文件中添加aop配置

  • 测试
ApplicationContext ctx = new ClasspathXMLApplicationContext ( "applicationXXX.xml" ) ;
Object obj = ctx . getBean ( "id" ) ;
obj . xxx () ;
  • 结论
从实验的结果中,发现 AOP 灵活度非常高,当需要或不需要前置或后置通知时,只需要进行配置即可。

3.2 AOP使用场景

在业界公认的包含以下场景:
  • 日志
                会降低日志输出灵活度,没有办法进行个性化设置
  • 权限
                如果下沉到了service层,那么基本已经没有太大意义。
  • 事务管理
                由于事务管理基本上是一成不变的,所以是最适合的使用场景。

http://chatgpt.dhexx.cn/article/hD2nT6rR.shtml

相关文章

2019泰迪杯C题案例分析-python大数据自动化数据挖掘

第七届“泰迪杯”数据挖掘挑战赛——C 题&#xff1a;运输车辆安全驾驶行为的分析 一、问题背景二、研究问题三、分析问题excel的批量处理时间、速度、方向角的处理经纬度的处理大数据处理的优化 一、问题背景 车联网是指借助装载在车辆上的电子标签通过无线射频等识别技术&am…

利用SPSS Modeler进行数据挖掘——探究不同程序语言的就业情况

欢迎加入程序员QQ交流群&#xff5e;&#xff5e;&#xff1a;859022876 程序员 本次SPSS Modeler项目实战&#xff0c;是我个人课余做的一个简单案例&#xff0c;因为本人也是互联网大家庭中的一员&#xff0c;因此最关心的必定是程序语言的未来走势和就业情况&#xff0c;于是…

数据挖掘实战—餐饮行业的数据挖掘之数据探索(EDA)

文章目录 引言一、前期准备1.目标定义与任务理解 二、数据采集与抽样三、数据探索1.数据质量分析1.1缺失值分析1.1.1缺失值可视化1.1.2描述性统计1.1.3统计缺失数与缺失率 1.2异常值分析1.2.1 3σ原则1.2.2箱型图分析 1.3一致性分析1.4重复数据处理 2.数据特征分析2.1分布分析2…

数据挖掘实战—餐饮行业的数据挖掘之数据预处理

文章目录 引言一、数据清洗1.缺失值处理1.1 拉格朗日插值法1.2牛顿差值法 2.异常值的处理 二、数据集成1.实体识别2.冗余属性识别3.数据变换3.1 简单函数变换3.2 规范化3.2.1 最小-最大规范化3.2.2 零-均值规范化&#xff08;标准化&#xff09;3.2.3 小数定标规范化 3.3 连续属…

数据挖掘案例:建立客户流失模型

随着市场竞争的加剧&#xff0c;中国电信面临的压力越来越大&#xff0c;客户流失也日益增大。从统计数据看&#xff0c;今年固话小灵通的销户数已经超过了开户数。面对如此严峻的市场形式&#xff0c;当务之急就是要尽全力减少客户的流失。因此&#xff0c;利用数据挖掘方法&a…

数据挖掘实战案例——客户细分

我们首先来看看原始数据 具体代码与原始数据可以在我的GitHub中git clone一下学习 代码与数据github地址 共26663条数据 此次分析是想对根据客户的购买情况对客户进行细分 分析用户的购买消费行为 首先读取csv import pandas as pd #import numpy as np trad_flow pd.read_…

浅谈数据挖掘

一、数据挖掘起源 人们迫切希望能对海量数据进行深入分析&#xff0c;发现并提取隐藏在其中的信息&#xff0c;以更好地利用这些数据。但仅以数据库系统的录入、查询、统计等功能&#xff0c;无法发现数据中存在的关系和规则&#xff0c;无法根据现有的数据预测未来的发展趋势…

Python数据分析挖掘案例:Python爬虫助力疫情数据追踪

通过学习Python数据分析挖掘案例&#xff0c;可以掌握通过Python爬虫获取的数据进行处理以及可视化分析的主要方法和技能&#xff0c;并为后续相关课程学习及将来从事数据分析工作奠定基础。 新冠病毒疫情在武汉突然爆发&#xff0c;确诊病例、疑似病例、死亡病例等数据牵动着每…

【数据挖掘案例】财政收入影响因素分析及预测模型

案例来源自《Python 数据分析与挖掘实战》第 13 章&#xff1a;财政收入影响因素分析及预测模型 案例目的&#xff1a;预测财政收入 1 数据的基本描述性分析 数据 字段含义 社会从业人数(x1 )、 在岗职工工资总额&#xff08;x2&#xff09;、社会消费品零售总额(x3)、城镇…

python数据挖掘案例系列教程——python实现搜索引擎

全栈工程师开发手册 &#xff08;作者&#xff1a;栾鹏&#xff09; python数据挖掘系列教程 今天我们使用python实现一个网站搜索引擎。主要包含两个部分。网站数据库的生成、搜索引擎。其中搜索引擎部分我们使用单词频度算法、单词距离算法、外部回值算法、链接文本算法、pag…

工业数据挖掘实例

智能的基础是智能决策&#xff0c;所有的决策都来自于分析。所以简单说所有的智能都是做好两件事&#xff1a;收集数据&#xff0c;使用数据。数据挖掘技术根据业务数据不同有不同的应用场景。在我以往工作中主要在以下领域有应用尝试&#xff1a; 市场营销&#xff1a;用数据…

[数据挖掘案例]逻辑回归LR模型实现电商商品个性化推荐

目录 一、问题描述 二、数据摸底 三、数据清洗和特征筛选 3.1 数据抽取和清洗 3.2 特征筛选&#xff1a;决策树 3.3 特征分布转换 3.4 特征共线性检查 四、模型搭建 4.1 数据集 4.2 模型训练 4.3 模型验证 五、模型上线效果跟踪 一、问题描述 在电商平台中&#xff…

数据挖掘案例(2):用户画像

内容分为两个部分&#xff1a;     第一部分&#xff1a;用户画像概述     第二部分&#xff1a;用户画像案例 数据和源码 移步到Github &#xff1a; https://github.com/Stormzudi/Data-Mining-Case 邮箱&#xff1a;442395572qq.com 目录 第一部分&#xff1a;1…

数据挖掘案例实战:利用LDA主题模型提取京东评论数据(一)

泰迪智能科技&#xff08;数据挖掘平台&#xff1a;TipDM数据挖掘平台&#xff09;最新推出的数据挖掘实战专栏 专栏将数据挖掘理论与项目案例实践相结合&#xff0c;可以让大家获得真实的数据挖掘学习与实践环境&#xff0c;更快、更好的学习数据挖掘知识与积累职业经验 专栏…

数据挖掘案例实战:利用LDA主题模型提取京东评论数据(二)

泰迪智能科技&#xff08;数据挖掘平台&#xff1a;TipDM数据挖掘平台&#xff09;最新推出的数据挖掘实战专栏 专栏将数据挖掘理论与项目案例实践相结合&#xff0c;可以让大家获得真实的数据挖掘学习与实践环境&#xff0c;更快、更好的学习数据挖掘知识与积累职业经验 专栏…

数据挖掘学习(四)——常见案例总结

笔者是一个痴迷于挖掘数据中的价值的学习人&#xff0c;希望在平日的工作学习中&#xff0c;挖掘数据的价值&#xff0c;找寻数据的秘密&#xff0c;笔者认为&#xff0c;数据的价值不仅仅只体现在企业中&#xff0c;个人也可以体会到数据的魅力&#xff0c;用技术力量探索行为…

数据挖掘实例1:亲和性分析示例(代码、注释、运行结果)

前言 本实例采用python3环境&#xff0c;编辑器采用Jupyter Notebook&#xff0c;安装使用方法请参考&#xff0c;本实例中所用到的附件内容放在文末&#xff0c;如果想要自行运行一下代码&#xff0c;可以尝试一下。 Jupyter Notebook介绍、安装及使用教程 亲和性分析示例 …

Python数据挖掘 数据预处理案例(以航空公司数据为例)

Python数据预处理 一、内容&#xff1a; 1、数据清洗 2、数据集成 3、数据可视化 二、实验数据 根据航空公司系统内的客户基本信息、乘机信息以及积分信息等详细数据&#xff0c;依据末次飞行日期( LAST_FLIGHT_DATE)&#xff0c;以2014年3月31日为结束时间&#xff0c;选取…

Axure 9.0.0.3712 授权码

更新日志 2020年8月4日&#xff0c;Axure 更新了最新的版本&#xff0c;本次的版本号为 Axure RP 9.0.0.3712&#xff0c;具体更新内容如下&#xff1a; 自从Axure发布了9.0版本以后&#xff0c;很多小伙伴之前使用的注册码已经失效了&#xff0c;为了不影响想体验的小伙伴&am…

axure8.1 授权码

Licensee: University of Science and Technology of China (CLASSROOM) Key: DTXRAnPn1P65Rt0xB4eTQ4bF5IUF0gu0X9XBEUhM4QxY0DRFJxYEmgh4nyh7RtL 原文链接&#xff1a;http://blog.csdn.net/quanqinyang/article/details/78217464