Spring 与 Servlet-1

news2024/11/15 2:06:20

整合 Spring 和 Servlet

DAO 使用 JDBC 通过模板类进行整合,模板类由 Spring 框架提供,只需进行配置即可

1、依赖:spring-jdbc 和连接池 druid、数据库驱动 mysql-connect-java

2、引入了 IoC、DI 后对象的创建完全交给 Spring 负责,只需要进行配置即可,所以在 Spring 的核心配置文件 applicationContext.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
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 配置连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test?serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    <!-- 配置 jdbc 模板类对象 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

3、定义 DAO 接口和对应的实现类,如果有必要还需要定义对应的实体类

public interface IUserDao {
    public int insert(User user);
}
public class UserDaoImpl implements IUserDao{
    private JdbcTemplate jdbcTemplate; //需要添加对应的 set 方法
    public int insert(User user) {
        return jdbcTemplate.update("insert into tb_users(username,password) values(?,?)", 
        user.getUsername(),user.getPassword()); }
}

4、配置DAO

<bean id="userDao" class="com.yan.dao.UserDaoImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

5、测试

public class Test1 {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        IUserDao userDao = ac.getBean("userDao", IUserDao.class);
        User user=new User();
        user.setUsername("zhangsan");
        user.setPassword("123456");
        int res=userDao.insert(user);
        System.out.println(res); }
}

Spring 整合 Servlet 问题就是在 Servlet 中如何访问受管 bean?

1、添加依赖:spring-web 和 servlet-api,由于服务器中一般包含了 servet-api 相关的 jar 包,所以这里的依赖的 scope 应该设置为 provider,这个 servlet-api 依赖不会打包到应用中

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.27</version>
</dependency>
<dependency>
    <gruopId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

2、在 src/main 目录下创建 webapp/WEB-INF 文件夹,添加 web 应用的核心配置文件

web.xml在应用启动时需要通过 xxx 加载 spring 的配置文件,并创建对应的 IoC/DI 容器,再将容器存储到 application对象中,供所有用户共享使用

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
    <!-- 配置 Spring 核心配置文件的名称和位置 -->
    <context-param> 上下文参数,供 ContextLoaderListener 使用
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
<!-- 当应用启动时,也就是 application 对象创建时,自动创建 IoC 容器并存储到 application 对象中,供
所有用户共享访问 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

在 web 应用中使用 WebApplicationContext 引用 IoC 容器,WebApplicationContext 接口是 ApplicationContext接口的子接口,主要添加了针对 web 应用的相关方法

3、定义控制器测试

public class MyController extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取 applicationContext 对象
        ApplicationContext ac= 
    WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());//通过工具类获取
//IoC 容器的引用,参数为 application 对象,获取 application 对象的方法由 HttpServlet 父类提供
        Date now=ac.getBean("now", Date.class);
        System.out.println(now);
    }
}

针对 servlet 配置

<servlet>
    <servlet-name>test</servlet-name>
    <servlet-class>com.yan.action.MyController</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>test</servlet-name>
    <url-pattern>/test.do</url-pattern>
</servlet-mapping>

web 应用组件

1、Servlet 通过映射的 url 地址的访问触发执行,或者页面跳转触发执行。3 生命周期方法 init-service-destroy

2、Filter 通过映射的 url 地址的访问触发执行,就是当访问某个地址时,会在执行目标程序之前或者之后进行一些额外的处理,当然也可以生成响应替代目标访问结果。实际上就是一种 AOP 编程

3、Listener 通过特定事件触发执行

监听 request 对象:

监听创建和销毁 ServletRequestListener

监听针对 request 的 attribute 的增删改操作 ServletRequestAttributeListener

监听 session 对象

创建和销毁 HttpSessionListener

针对 session 的 attribute 的增删改操作 HttpSessionAttributeListener

针对 session 的激活钝化操作 HttpSessionActivationListener

针对 bean 的绑定操作 HttpSessionBindingListener

监听 application 对象

创建和销毁 ServletContextListener

针对 application 的 attribute 的增删改操作 ServletContextAttributeListener

AOP

在应用中使用日志工具,例如 log4j

1、添加依赖 log4j

2、通过工具类获取对应的日志记录器对象

private static final Logger logger= LoggerFactory.getLogger(UserServImpl.class);

3、调用日志记录器中的方法实现日志输出 logger.debug(“需要输出到日志中的信息”);

如果把通用系统需求加入到处理业务需求的类中,那么业务类就会变得很复杂和零乱。甚至可能会喧宾夺主,而且以后要变更系统需求的时候,将给软件带来很大的维护量

分散关注的思路

1、将通用需求功能从不相关类之中分离出来

2、能够使得很多类共享一个行为,一旦行为发生变化,不必修改很多类,只要修改这个行为就可以

3、AOP 就是这种实现分散关注的编程方法,它将关注【通用功能】封装在方面【切面】中

代理模式

意图:为其他对象提供一种代理以控制对这个对象的访问。

在这里插入图片描述

优点: 1、职责清晰。 2、高扩展性。 3、智能化。

缺点:

1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。

2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

注意事项: 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

静态代理

需要聘请一个歌手来唱歌助兴,实际上没有办法直接访问歌手,而是通过代理人访问歌手

定义接口

public interface 会唱歌的{
    public void 唱歌();
}

被代理对象所属的类

//注意这里不要讨论类与对象的问题,仅仅是了方便理解
public class 刘德华 implements 会唱歌的{
    @Override
    public void 唱歌(){
    System.out.println("冷冷的冰雨~~~");
}
}

代理对象所属的类

public class 宋喆 implements 会唱歌的{
    private 会唱歌的 被代理对象;
    public 宋喆(会唱歌的 target){
        this.被代理对象=target;
    }
    Override
    public void 唱歌(){
        System.out.println("签订演艺合同...");
        //由代理人限制对被代理对象的访问
        this.被代理对象.唱歌();
        System.out.println("收钱");
    }
}

测试程序

会唱歌的 obj = new 宋喆(new 刘德华());
obj.唱歌();

缺点:需要手动创建子类,当需要被代理的元素较多时工作量会明显变大

动态代理

动态代理有 JDK 动态代理和 CGLib 动态代理两种

在这里插入图片描述

定义接口

public interface 会唱歌的{
    public void 唱歌();
}

被代理对象所属的类

//注意这里不要讨论类与对象的问题,仅仅是为了方便
public class 刘德华 implements 会唱歌的(){
    @Override
    public void 唱歌(){
        System.out.println("冷冷的冰雨~~~");
    }
}

使用 JDK 的动态代理时没有对应的代理类,这个代理对象是动态生成的,这里需要定义一个回调处理类

public class 回调处理类 implements InvocationHandler{
    private Object 被代理对象;
    public 回调处理类(Object obj){
        this.被代理对象=obj;
    }
    Override
    public Object invoke(Object proxy,Method method, Object[] args) throw Throwable{
        System.out.println("签订演艺合同...");
        Object res = method.invoke(this.被代理对象,args);//通过反射机制调用被代理对象中的对应方法
        System.out.println("收钱");
        return res;
    }
}

测试调用

//创建一个代理对象,参数1为所用的类加载器对象,参数2为代理的接口数组,参数为回调接口实现对象
    会唱歌的 obj = (会唱歌的)Proxy.newPrixyInstance(会唱歌的.class.getClassLoader(),
        new Class[]{会唱歌的.class},new 回调处理类(new 刘德华()));
    obj.唱歌();

AOP 实现的原理就是 JDK 动态代理模型。JDK 动态代理只能为实现接口的 Java 类创建代理对象;CGLib 可以为任何 Java 类提供代理对象。

总结

1、静态代理是通过在代码中显式定义一个业务实现类一个代理,在代理类中对同名的业务方法进行包装,用户通过代理类调用被包装过的业务方法;核心:手动创建一个与目标类相同接口的子类,包装目标类。

2、JDK 动态代理是通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法;通过 jdk 提供的反射包中 Proxy 类动态的创建一个与目标类实现相同接口的子类对象,包装目标。

3、CGlib 动态代理是通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理。通过CGlib 提供的 Enhancer 这个类,动态的创建一个目标类的子类对象,包装目标类。在逐步对 JDK 动态代理优化后,在调用次数较少的情况下,JDK 代理效率高于 CGLIB 代理效率,只有当进行大量调用的时候,jdk6 和 jdk7 比 CGLIB 代理效率低一点,但是到 jdk8 的时候,jdk 代理效率高于 CGLIB 代理。

Hello Spring AOP

1、依赖 spring-aop

Spring AOP 默认采用的是 JDK 动态代理,所以要求接口;但是实际上没有接口 Spring 会切换到 CGLib 动态代理。

2、定义接口

public interface 会唱歌的{
    public void 唱歌();
}

3、被代理对象所属的类

//注意这里不要讨论类与对象的问题,仅仅是了方便理解
public class 刘德华 implements 会唱歌的{
    @Override
    public void 唱歌(){
    System.out.println("冷冷的冰雨~~~");
}
}

4、代理对象所属的类

public class 前置处理类 implements MethodBeforeAdvice{
    @Override
    public void before (Method method,Object[] args,Object tsrget)throw Throwable{
        //参数1是调用的方法对象,参数2是调用的方法参数,参数3是目标对象
        System.out.println(target);
        System.out.println("签订演艺合同...");
    }
}

5、添加对应的配置

<bean id="被代理对象" class="com.test2.刘德华"/>
<bean id="回调处理对象" class="com.test2.前置处理类"/>
<bean id="代理对象" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="被代理对象"/>
        <property name="interfaces"><!--配置被代理的接口 -->
            <value>com.test2.会唱歌的</value>
        </property>
        <property name="interceptorNames"><!--回调处理的对象名称 -->
            <value>回调处理对象</value>
        </property>
</bean>

6、测试调用

ApplicationContext ac = new
    ClassPathXmlApplicationContext("applicationContext.xml");
会唱歌的 s = ac.getBean("代理对象",会唱歌的.class);
s.唱歌();

概述 AOP

AOP 面向切面编程可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序增加动态控制功能的一种技术。AOP 的主要编程对象是切面,而切面模块化横切关注点

在应用 AOP 编程时仍然需要定义公共功能,但可以明确的定义这个功能在哪里,以什么方式应用,并且不必修改受影响的类。这样一来横切关注点就被模块化到特殊的对象即切面里

面向切面编程AOP通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式编程的一种衍生范型。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

基础概念

连接点:添加程序的位置,Spring 支持的颗粒度比较粗,只能是方法前、方法后等位置,不能是语句级

切入点:连接点的对象化表示,可以使用 AspectJ 的切入点表达式说面一系列连接点

通知:需要添加的程序

切面:切入点+通知

增强和织入

AOP 与 IoC 的联系与区别
相同点:都是寻求调用者与被调用者的解耦

不同点:

1、IoC 关注的是对象的创建、维护职责与对象的使用权(该使用权与调用者的功能紧密相关)解耦

2、AOP 关注的是功能本身的解耦

Spring 中 AOP 代理由 Spring 的 IoC 容器负责生成、管理,其依赖关系也由 IoC 容器负责管理。因此,AOP 代理可以直接使用容器中的其它 bean 实例作为目标,这种关系可由 IOC 容器的依赖注入提供。

Spring 创建代理的规则为:

1、默认使用 Java 动态代理来创建 AOP 代理,这样就可以为任何接口实例创建代理了

2、当需要代理的类不是代理接口的时候,Spring 会切换为使用 CGLIB 代理,也可强制使用 CGLIB。配置方法

<aop:aspectj-autoproxy proxyt-target-class="true"/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/675455.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:求1-3+5-7:用Python解决这个算术问题

求1-35-7: 用Python解决这个算术问题 介绍 在Python编程领域中&#xff0c;算术问题是我们经常会遇到的。今天&#xff0c;我们将介绍如何用Python求1-35-7这个算式的结果。这个问题看起来很简单&#xff0c;但如果你是初学者&#xff0c;可能会有点难以理解。不必担心&#…

嵌入式中编写可移植 C/C++ 程序的要点方法

以前做过两年 C 程序移植工作&#xff0c;从 Win32 平台移植到 Linux 平台。大约有上百万行 C/C代码&#xff0c;历时一年多。 在开发 Win32 版本时&#xff0c;已经强调了程序的可植性&#xff0c;无奈 Win32 团队里对 Linux 精通的人比较少&#xff0c;很多问题没有想到&…

InstructGPT论文解读

介绍 上图可以看出InstructGPT(PPO-ptx)及变体&#xff08;variant trained without pretraining mix&#xff09;(PPO)显著优于GPT&#xff0c;1.3B的InstructGPT优于175B的GPT&#xff0c;SFT作为RLHF第一阶段的模型效果比GPT好。当然结果是由人来评价的。 RLHF包含三个步骤…

多EIP下的UDP通信异常分析

背景 SRE和程序在测试DDos多EIP防御方案的过程中&#xff0c;发现多EIP模式下, 监听的UDP端口连接会出现客户端访问异常。 表现为客户端发送一次数据后服务端这边主动断开了&#xff0c;或是客户端和服务端同时断开。 该问题会导致业务在多EIP方案下无法达到预期效果&#xff0…

【Visual Studio】Qt 获取系统时间,并实时更新时间,使用 C++ 语言,配合 Qt 开发串口通信界面

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 这个需求来源于这个工程&#xff1a;【Visual Studio】Qt 的实时绘图曲线功能&#xff0c;使用 C 语言&#xff0c;配合 Qt 开发串口通信界面。 文章目录 Qt…

chatgpt赋能python:Python求和1-100的方法

Python求和1-100的方法 Python语言简介 Python是一个广泛使用的高级编程语言&#xff0c;其设计哲学强调代码可读性和语法简洁性。Python语言作为一门多范式的编程语言&#xff0c;支持对象、函数式和结构化编程等多种形式。Python应用领域广泛&#xff0c;如机器学习、桌面应…

chatgpt赋能python:Python求1!:介绍

Python求1!&#xff1a;介绍 在Python编程中&#xff0c;阶乘是一个常见的数学运算。阶乘指定的数的所有小于或等于其本身的正整数之积&#xff0c;例如&#xff0c;1!等于1&#xff0c;2&#xff01;等于2乘以1&#xff0c;3!等于3乘以2乘以1&#xff0c;以此类推。 在这篇文…

【工程项目管理】工程项目管理实践报告

前言&#xff1a; 1.大学课程的大作业&#xff0c;觉得存起来也没什么用就干脆发出来了。。。 2.很可能有不严谨之处&#xff0c;各位看官如若发现欢迎指出~ 创作者文章管理系统 1 实践环节作业1&#xff1a;选题及任务分解WBS &#xff08;1&#xff09;选题 a.项目名称&a…

【1 beego学习 -MAC框架与ORM数据库】

0 beego的启动流程 1 入口 package mainimport ( //全局使用的路由和models_ "studyDemo/models"_ "studyDemo/routers"beego "github.com/beego/beego/v2/server/web" )func main() {beego.Run() }2 根据请求路由加载对应的控制器 package r…

【计算机组成原理】微程序控制器

目录 一、微程序控制器概述 二、微程序控制器设计方法 三、微指令执行过程 四、控制字段的编码方式 五、下址字段的设计方法 六、微程序入口地址的产生方法 一、微程序控制器概述 微程序&#xff1a;微指令构成的有序集合&#xff0c;一条指令对应一段微程序 微指令&…

【小沐学Android】Material Design设计规范之颜色篇

文章目录 1、简介1.1 Android1.2 Material Design 2、Material Design 12.1 材料设计2.2 颜色 3、Material Design 23.1 材料系统3.2 颜色 4、Material Design 34.1 颜色样式4.2 配色方案4.3 Material Theme Builder 结语 1、简介 1.1 Android 谷歌在2007年发布了第一个测试版…

chatgpt赋能python:Python清除代码:让你的项目更加优美

Python清除代码&#xff1a;让你的项目更加优美 随着时间推移和项目规模扩大&#xff0c;代码中可能会出现许多冗余、无用或重复的代码。这不仅会让代码难以维护&#xff0c;还会降低代码的性能和可读性。而Python作为一种高级编程语言&#xff0c;提供了许多工具和技术来清除…

牛客练习赛108 E.琉焰(非树边性质/线段树分治+可撤销并查集 or LCT)

题目 思路来源 官方题解 题解 针对每个连通块&#xff0c;单独考虑&#xff1a; 一方面&#xff0c; 任取连通块的某棵生成树&#xff0c; 对于任意非树边(u,v)&#xff0c;把树边u到v上的所有边都选中&#xff0c;即被覆盖1次&#xff0c; 任取某个非树边集合S&#xff…

LangChain for LLM Application Development 基于LangChain开发大语言应用模型(下)

以下内容均整理来自deeplearning.ai的同名课程 Location 课程访问地址 DLAI - Learning Platform Beta (deeplearning.ai) LangChain for LLM Application Development 基于LangChain开发大语言应用模型&#xff08;上&#xff09; 一、LangChain: Q&A over Documents基于文…

bert4rec简介

1、bert4rec提出动机 用户行为动态变化&#xff0c;序列行为建模取得了不错的效果 单向结构限制了行为序列中隐藏信息的挖掘 序列神经网络顺序依赖&#xff0c;无法并行计算 为此&#xff0c;提出了 基于双向self-attention和Cloze task的用户行为序列建模方法。据我们所知…

解决Jenkins报错

解决Jenkins报错 1 linux空间不够问题1.1 报错现象1.2 定位问题1.3 解决措施 2 bash问题2.1 问题现象2.2 问题定位2.3 解决措施 3 虚拟环境问题3.1 问题现象3.2 问题定位3.3 解决措施 4 jenkins构建完成但一直转圈问题4.1 问题现象4.2 问题定位4.3 解决措施 5 jenkins自动化部署…

C高级6.24

一、整理grep、find、cut、tar、apt-get、dpkg、ln、ln-s指令 1.grep ----->查找字符串 grep 字符串 文件名 -w:按单词查找 -R:实现递归查找&#xff0c;主要用于路径是目录的情况 -i:不区分大小写 -n:显示行号 grep -w "^ubuntu" /etc/passwd ---->查找以ub…

【深度学习】RepVGG解析和学习体会

文章目录 前言0. Vgg1.RepVGG Block 详解 前言 论文名称&#xff1a;RepVGG: Making VGG-style ConvNets Great Again 论文下载地址&#xff1a;https://arxiv.org/abs/2101.03697 官方源码&#xff08;Pytorch实现&#xff09;&#xff1a;https://github.com/DingXiaoH/RepV…

今天是世界Wi-Fi日!

很多人都不知道&#xff0c;今天其实是世界Wi-Fi日&#xff1a; 这个特殊的纪念日&#xff0c;是由无线宽带联盟&#xff08;Wireless Broadband Alliance&#xff09;确定的&#xff0c;并得到了互联城市咨询委员会 &#xff08;CCAB&#xff09;等组织的大力支持。 无线宽带联…

数据处理神器tidyverse!教你如何秒速搞定数据处理!

一、前言 在R语言中&#xff0c;tidyverse是一个庞大的数据分析生态系统&#xff0c;它由一系列数据可视化和数据处理软件包组成&#xff0c;能够极大地提高数据分析的效率和准确性。 在使用 Tidyverse 的过程中&#xff0c;我们会经常用到以下几个工具&#xff1a; ggplot2&am…