逆向工程、Spring框架IOC、AOP学习

news2024/11/15 19:39:09

系列文章目录

第一章 基础知识、数据类型学习
第二章 万年历项目
第三章 代码逻辑训练习题
第四章 方法、数组学习
第五章 图书管理系统项目
第六章 面向对象编程:封装、继承、多态学习
第七章 封装继承多态习题
第八章 常用类、包装类、异常处理机制学习
第九章 集合学习
第十章 IO流、多线程学习
第十一章 仓库管理系统项目
第十二章 员工管理系统、多表查询、反射实现DBHelper学习
第十三章 DML、DDL、数据库对象学习
第十四章 网络编程、各种标签、CSS学习
第十五章 ECMAScript、BOM学习
第十六章 DOM、jQuery学习
第十七章 Servlet、jsp、Cookie、Ajax学习
第十八章 融资管理系统项目
第十九章 MyBatis框架学习
第二十章 逆向工程、Spring框架IOC、AOP学习


文章目录

  • 系列文章目录
  • 前言
  • 一、逆向工程
    • 1. 逆向工程的使用步骤
  • 二、初识Spring框架
    • 1. Spring简介
    • 2. IoC控制反转
      • 2.1 IoC介绍
      • 2.2 IoC代码实现
        • 2.2.1 Dept实体类
        • 2.2.2 DeptMapper数据持久层
        • 2.2.3 DeptService业务层
        • 2.2.4 DeptTest控制层
        • 2.2.5 applicationContext框架核心文件
    • 3. AOP面向切面编程
      • 3.1 什么是切面(举例子)
      • 3.2 什么是切面(官方话)
      • 3.3 AOP的应用场合
      • 3.4 AOP中的几个要素
      • 3.5 AOP的分类
      • 3.6 AOP代码实现
        • 3.6.1 DeptAdvice横切代码类
        • 3.6.2 applicationContext.xml配置文件更新
        • 3.6.3 DeptServiceImpl实现类更新
        • 3.6.4 运行结果
    • 4. TX简介
  • 总结


前言

本文会讲述:
逆向工程介绍
Spring框架的介绍与使用
IoC控制反转技术
AOP面向切面技术
在下攸攸太上,正在投骰子决定地球人生死。


一、逆向工程

逆向工程在本文仅做介绍;
逆向工程,名字其实不太符合实际,因为实现的其实是使用代码编写代码,应该叫代码生成工程 ,但多半人类都这么叫,我一个外星人也没法跟他们争。
逆向工程需要配置文件generatorConfig.xml

1. 逆向工程的使用步骤

在配置文件中
1、设置数据库驱动
2、设置生成的pojo实体类的位置
3、设置生成的Mapper映射文件的位置
4、设置生成的Mapper接口的位置
5、根据数据库表生成pojo类
6、执行调用方法

二、初识Spring框架

1. Spring简介

Spring是一个敢于提出新想法的某个略微伟大的人类提出的,为了解决JavaEE项目臃肿低效的问题,Spring的理想是,以Spring调用三层架构,使三层架构关系更加紧密,代码量更少,可扩展性更佳。

Spring分为三个主要的部分IoC(DI)、AOP、TX
IoC控制反转:帮助开发者创建对象,交给Spring容器控制
DL依赖注入:当前类依赖的对象,由Spring容器自动注入
AOP面向切面编程:提高代码的扩展性,有点像过滤器,针对方法
TX声明式事务管理:事务管理机制。事务过程不需要开发者编写,只需要声明出哪些方法需要进行事务管理。

2. IoC控制反转

2.1 IoC介绍

Inversion of Control:实现代码之间的解耦(降低耦合度)
控制:对类实例化的控制,指的是创建对象这个事情。
反转:以前由程序员实例化的过程,转交给Spring进行实例化。
可以想象一下:生成类交给逆向工程、生成对象就交给IoC、释放对象交给垃圾处理机制,此代码要我何用??
但Spring的目标就是这样,一切与逻辑无关的代码交给别人,开发者只管实现逻辑

2.2 IoC代码实现

2.2.1 Dept实体类
package entry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
    private Integer deptno;
    private String dname;
    private String loc;
}
2.2.2 DeptMapper数据持久层
package mapper;
public class DeptMapper {
    public void selectAll(){
        System.out.println("I am IronMan");
    }
}
2.2.3 DeptService业务层
package service;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import mapper.DeptMapper;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DeptService {
    private DeptMapper deptMapper;
    public void selectAll(){
        deptMapper.selectAll();
    }
}
2.2.4 DeptTest控制层
package test;
import entry.Dept;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.DeptService;
public class DeptTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Dept dept = applicationContext.getBean("dept", Dept.class);
        dept.setDeptno(100);
        dept.setDname("原来如此");
        dept.setLoc("原!来!如!此!");
        System.out.println(dept);
        Dept deptSet = applicationContext.getBean("deptSet", Dept.class);
        System.out.println(deptSet);
        DeptService deptService = applicationContext.getBean("deptService", DeptService.class);
        deptService.selectAll();
    }
}
2.2.5 applicationContext框架核心文件
<?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">
    <!--设置使用dept的无参构造器创建对象-->
	<bean id="dept" class="entry.Dept"/>
	<!--设置使用dept的有参构造器创建对象-->
	<bean id="deptSet" class="entry.Dept">
	    <constructor-arg name="deptno" value="199"/>
	    <constructor-arg index="1" value="客服部"/>
	    <constructor-arg name="loc" value="南京"/>
	</bean>
	<!--配置deptMAapper对象-->
	<bean id="deptMapper" class="com.jr.mapper.DeptMapper"/>
	<!--配置DeptService对象-->
	<bean id="deptService" class="com.jr.service.DeptService" autowire="byType">
	    <!--Spring的属性方式自动注入-->
	    <!--<property name="deptMapper" ref="deptMapper"/>-->
	    <!--Spring的构造器方式自动注入-->
	   <!-- <constructor-arg name="deptMapper" ref="deptMapper"/>-->
	</beans>

3. AOP面向切面编程

AOP:Aspect Oriented Programming面向切面编程,目的在于提升代码的扩展性
为了解决“将代码提取出去,还能作用回各个方法”的问题。
按照软件重构思想的理念,在OOP中通过抽象把相同的代码抽取到父类中(纵向抽取),但无法通过抽象父类的方式消除重复性的横切代码(如事务处理这种非业务性的重复代码),而AOP就是为了解决将分散在各个业务逻辑代码中的相同代码通过横向切割的方式抽取到一个独立的模块中。

3.1 什么是切面(举例子)

这么说有些复杂,大家可以想象制作汉堡的流水线,
前提:不同的汉堡,例如:深海鳕鱼堡、香辣鸡腿堡、芝士牛肉堡等,所有的汉堡,里面的汉堡肉不同,但两侧包裹着的面包总是相同的。
代码实现:我们给汉堡肉做成父类,不同的汉堡肉为不同的子类,我们要在每个子类里给不同的汉堡肉夹上相同的面包片,很麻烦对吧?我们可以进行改进
改进plus:我们可以把夹上面包片的方法提取到父类,然后不同的子类都可以调用,很方便对吧!但是我们还可以进行改进
改进ultra:我们把夹上面包片的方法单独提取出来一个类,告诉他,所有的汉堡肉,都夹上面包!

3.2 什么是切面(官方话)

可以理解为程序执行时的某个节点,或者更具体一点,在某个方法执行之前,执行之后等节点。
使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事务管理,日志记录等等。这些系统性的编程工作都可以独立编码实现,然后通过AOP技术再切入进系统即可。从而达到了 将不同的关注点分离出来的效果。

3.3 AOP的应用场合

AOP有特定的应用场合,它只适合具有横切逻辑的应用场合,如:性能检测,访问控制,事务控制,日志记录等。就像面向对象编程的关注点在于对象即类;而面向切面编程的关注的在于切面。

3.4 AOP中的几个要素

1、Aspect :切面,切入系统的一个切面。比如事务管理是一个切面,权限管理也是一个切面;
2、Join point :连接点,也就是可以进行横向切入的位置;
3、Advice :通知,切面在某个连接点执行的操作(分为: Before advice , After returning advice , After throwing advice , After (finally) advice , Around advice );
4、Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方;

3.5 AOP的分类

​AOP分为静态AOP和动态AOP。静态AOP是将切面代码直接编译到Java类文件中。动态AOP是指先将切面代码统一放到一个切面类里去,然后进行动态织入到指定的切点方法周围,从而实现AOP。Spring的AOP为动态AOP,实现的技术为: JDK提供的动态代理技术和CGLIB(动态字节码增强技术)。尽管实现技术不一样,但 都是基于代理模式,都是生成一个代理对象。

3.6 AOP代码实现

3.6.1 DeptAdvice横切代码类
package com.jr.service;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DeptAdvice {
    @Before("execution(* com.jr.service.DeptService.*(..))")
    public void check(){
        System.out.println("你谁啊?跟本大爷怎么说话?啊?");
        System.out.println("失敬失敬!原来是董事长阁下");
    }
    @After("execution(* com.jr.service.DeptService.*(..))")
    public void log(){
        System.out.println("诶!诶!董事长您慢走!");
        System.out.println("什么玩意!我恁爹!给爹滚!");
    }
}
3.6.2 applicationContext.xml配置文件更新

咱们的Spring框架都是注解来实现的,所以要定义一个扫描路径扫描Spring框架的注解,例如@Aspect、@Componet、@Before、@After等

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.3.xsd
                http://www.springframework.org/schema/tx
                http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    <context:component-scan base-package="com.jr"/>
    <aop:aspectj-autoproxy/>
    <!--加载jdbc属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--配置数据库环境-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${mysql.driver}"/>
        <property name="url" value="${mysql.url}"/>
        <property name="username" value="${mysql.username}"/>
        <property name="password" value="${mysql.password}"/>
    </bean>
    <!--配置sqlSessionFactory对象-->
    <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:SqlMapConfig.xml"/>
    </bean>
    <!--配置mapper映射文件的扫描路径-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.jr.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="factory"/>
    </bean>
    <!--配置Spring框架的注解扫描路径-->
    <context:component-scan base-package="com.jr"/>

    <!--配置spring注解模式下,生成动态代理类-->
    <aop:aspectj-autoproxy/>
    <!--配置事务管理器对象-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--注解模式下,事务传播策略的配置-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
3.6.3 DeptServiceImpl实现类更新

这回我们将service层写的标准一些,写成结构和实现类的关系。估计大家都能根据以下代码写出DeptService接口类

package com.jr.service.impl;

import com.jr.entry.Dept;
import com.jr.mapper.DeptMapper;
import com.jr.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class DeptServiceImpl implements DeptService {
    @Autowired //Spring进行自动注入
    private DeptMapper deptMapper;
    @Override
    public ArrayList<Dept> findAll() {
        return deptMapper.selectAll();
    }
    @Override
    public boolean addDept(Dept dept) {
        return deptMapper.insertDept(dept) == 1 ? true : false;
    }
    @Override
    public boolean updeptDept(Dept dept) {
        return deptMapper.updateDept(dept) == 1 ? true : false;
    }
}
3.6.4 运行结果

在这里插入图片描述

4. TX简介

首先,请看下文中的事务介绍
DML、DDL、数据库对象学习


没看也没关系哦,顶多就是有50%的可能性被我们星球的毁灭光线BiuBiu死。



恭喜你,是剩下的50%,简单来说,事务就是将一段连续的操作视为一个整体,一人失败全员回滚。
二次元看过来!!
这个事务,分明就是抄袭吉良吉影的败者食尘!!
玩笑就开到这里
下面我们更改我们的代码
首先在数据库中运行如下代码:

alter table dept add constraint ck_dept_loc check (loc != '北京' );

此代码能让dept表加入一个约束,使得loc列不能设为“北京”

其次将DeptServiceImpl类里的findAll方法改为如下:

@Override
public ArrayList<Dept> findAll() {
    System.out.println("22222222");
    Dept dept = new Dept();
    dept.setDeptno(122);
    dept.setDname("产品部");
    dept.setLoc("哈尔滨");
    int i = deptMapper.insertDept(dept);
    dept.setLoc("北京");
    i+=deptMapper.updateDept(dept);
    if(i==2){
        return deptMapper.selectAll();
    }else
     return null;
}

这段代码先进行新增操作,后进行修改操作,最后可能进行查询操作。
如果数据库版本较低,loc修改为北京不会成功,因为约束不允许,所以所有操作都会回滚,数据库里
但如果数据库版本高,他可能会认为你是误操作,会报错但是修改操作也会成功。
最后在applicationContext.xml配置文件中加入如下代码:

<!--事物的管理对象-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--注解模式下,事务传播策略的配置-->
<tx:annotation-driven transaction-manager="transactionManager"/>

总结

本文讲述了:
逆向工程:使用代码生成代码;
Spring框架:操作Service层,使Service层的代码量更少,可扩展性更佳;
IoC控制反转技术:创建一个对象帮你创建所有其他对象;
AOP面向切面技术:自动向所有功能的前后添加检查或记录的功能
在下是攸攸太上,我认为地球人都是大low炮。哇哈哈哈哈哈哈哈哈!

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

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

相关文章

linux服务器/虚拟机安装redis

py3安装&#xff08;慢的一批无语了&#xff09; wget http://cdn.npm.taobao.org/dist/python/3.6.5/Python-3.6.5.tgz && tar -zxvf Python-3.6.5.tgz && cd Python-3.6.5/ && ./configure --prefix/usr/local/python3 --with-ssl && make …

重磅!预读 New feature 提升再次提升20%+性能

在7月底发布的MogDB 5.0.8版本中&#xff0c;引入了几个新特性&#xff0c;其中的预读功能又将全表扫描能力提升了至少20%。 什么是MogDB 预读功能 数据库中的数据是按照一个个页面进行组织管理的&#xff0c;CPU以页面为单位对数据进行处理&#xff0c;这就使得CPU处理和I/O之…

AI模型:全能与专精的较量与未来潜力探讨

AI模型&#xff1a;追求全能还是专精&#xff1f; 随着人工智能技术的飞速发展&#xff0c;AI模型逐渐成为各个领域的焦点。近日&#xff0c;OpenAI即将推出的“草莓”模型&#xff0c;以其全能型的特点引起了广泛关注。在这篇文章中&#xff0c;我们将探讨全能型AI与专精型AI…

第十三章、 泛型

第十三章、 泛型 13.1 泛型语法 13.1.1 泛型的引入与入门 看一个需求 &#xff08;1&#xff09;. 请编写程序&#xff0c;在ArrayList中&#xff0c;添加3个Dog对象 &#xff08;2&#xff09;. Dog对象含有name和age&#xff0c;并输出name和age&#xff08;要求使用getXx…

IPv6和IPv4的主要区别

地址变化与转换&#xff1a; IPv6 二进制数有 128 位&#xff0c;IPv6 使用十六进制表示&#xff0c;中间使用 : 分隔。 简写&#xff1a; 将前面连续的 0 &#xff0c;使用 :: 表示。缩写只能使用一次&#xff0c;而且缩头不缩尾。 首部&#xff1a; 地址划分&#xff1a; IPv…

WEB:探索富文本编辑器的详细指南

请关注微信公众号&#xff1a;拾荒的小海螺 博客地址&#xff1a;http://lsk-ww.cn/ 1、简述 富文本编辑器&#xff08;Rich Text Editor, RTE&#xff09;是一种允许用户在不需要编写HTML或CSS代码的情况下创建和编辑复杂文本内容的工具。无论是博客平台、内容管理系统&…

pnpm 查看库的所有版本

1、最近在做图布局的时候&#xff0c;发现默认版本是beta版 2、那么我们如何来查看远程库中有什么版本可以安装呢&#xff1f; 3、使用命令&#xff1a; pnpm view antv/layout versions pnpm view 这里替换成要查看的库名 versions

Flutter-->自定义容器Widget(类比Android自定义ViewGroup)

上一篇Flutter–&#xff1e;自定义Widget(类比Android自定义View) 介绍了如何自定义一个Widget, 这一篇文章介绍如果自定义容器Widget, 相当于Android中的ViewGroup Android自定义ViewGroup 先来简单介绍一下Android中自定义的ViewGroup: class CustomViewGroup(context: …

树上dp+分组背包类问题

今天也是无意间看到了一个树上dp分组背包类的问题&#xff0c;有些难度的&#xff0c;不好想的嘞&#xff0c;终究还是一个蒟蒻罢了&#xff0c;唔无捂误 话不多说直接看题 P1273 有线电视网 在说明这道题之前&#xff0c;还有一个要提醒的地方就是&#xff0c;树上dp&#…

在 DataOps 体系建设中,主动元数据是何角色?

首先&#xff0c;主动元数据是相对静态元数据而言&#xff0c;它是一种动态、智能化的元数据管理技术&#xff0c;能够将传统静态元数据的被动等待变为实时在线、主动触发&#xff0c;推动数据探查、开发、测试、部署、运维和监控等数据治理工作高效运转&#xff0c;为数据的治…

springWeb介绍、以及SpringWeb的搭建

ssm框架 早期 ssm springstrtuts2mybatis 现在 ssm springspringwebmybatis springweb运行流程 1、SpringWeb概述 SpringWeb是spring框架中的一个模块&#xff0c;基于Servlet API构建的web框架&#xff0c;springweb是Spring为web层开发提供的一套完备的解决方案。在we…

Java毕业设计 基于SSM校园心理咨询服务平台

Java毕业设计 基于SSM校园心理咨询服务平台 SSM 校园心理咨询服务平台 功能介绍 学生: 注册 登录 首页 心理测试 心理文章 心理导师 在线交流 关于我们 搜索 学生中心 我的咨询问题 我的测试结果 我的预约 我的发言 我的收藏 账户信息 教师&#xff1a;登录 发布文…

Linux——nginx 负载均衡

常规的web服务器一般提供对于静态资源的访问&#xff0c;比如说&#xff1a;图片、web样式 网站提供的大部分交互功能都需要web编程语言的支持&#xff0c;而web服务对于程序的调用&#xff0c;不管编译型语言还是解释型语言&#xff0c;web服务同将对于应用程序的调用递交给通…

音频变声怎么弄?(实测好用)快来试试这6个AI变声工具

音频变声怎么弄&#xff1f;随着短视频平台和社交平台的发展&#xff0c;很多小伙伴们会自己拍摄视频分享到平台上&#xff0c;还有一些视频创作者会制作有趣的视频吸引观众。而视频配音就是锦上添花&#xff0c;很多人觉得自己的声音不好听&#xff0c;想要实现录音音频变声&a…

结合ollama gemma2:2b大模型来实现数据分析系统的智能交互

在最近的人员风险行为分析系统开发过程中&#xff0c;需要解决一个问题&#xff1a;在缺乏GPU资源的情况下&#xff0c;如何提升智能交互能力。​我们探索并研究了集成gemma2:2b模型的可行性&#xff0c;这一举措旨在在有限的硬件条件下&#xff0c;为我们的系统注入更高级别的…

如何理解进程

一、进程的概念 进程&#xff1a;顾名思义&#xff0c;就是一个完整执行程序的过程。没错&#xff0c;就是这么简单&#xff0c;但是在程序执行的过程之中&#xff0c;系统会为这个执行的程序分配内存资源&#xff0c;这些过程也包含在进程当中。 进程是动态的&#xff0c;是程…

css-50 Projects in 50 Days(2)

html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>步骤条</title><link rel"style…

基于混沌麻雀搜索算法的光伏MPPT控制MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 此模型主要研究光伏系统MPPT控制&#xff0c;通过将麻雀搜索算法引入至MPPT控制策略中&#xff0c;在模型中通过改变光照强度&#xff0c;来验证算法引入的有效性。模型中包含麻雀搜索算法MPPT与混…

单链表——随机链表的复制

深拷贝&#xff0c;就是将原链表彻底的拷贝&#xff0c;当我们观察这个链表时我们会发现&#xff0c;val与next都比较好拷贝&#xff0c;难点就是在random的拷贝&#xff0c;因为我们需要知被拷贝的节点的random指向的是哪个&#xff0c;所以我们很容易想到的方法就是从头遍历链…

从开题到答辩:ChatGPT超全提示词分享!(上)【建议收藏】

在浩瀚的知识领域中&#xff0c;提问的艺术是探索真理的钥匙。在这个信息爆炸的时代&#xff0c;深入探索知识的海洋&#xff0c;不仅需要热情和毅力&#xff0c;更需要正确的方法和工具。学术研究是一个复杂而严谨的过程&#xff0c;涉及从选题、文献综述到研究设计、数据收集…