Spring-Aop及jdbc总结
什么是Aop
AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
AOP相关概念
切面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的 Advisor或拦截器实现。
连接点(Joinpoint): 程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
切入点(Pointcut): 指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点:例如,使用正则表达式。 Spring定义了Pointcut接口,用来组合MethodMatcher和ClassFilter,可以通过名字很清楚的理解, MethodMatcher是用来检查目标类的方法是否可以被应用此通知,而ClassFilter是用来检查Pointcut是否应该应用到目标类上
如execution(* com.cqucc.dao.*.*(..))
第一部分*号表示任意返回值
第二部分*号com.DJX.Dao.*表示在com.DJX.Dao包下的任何类
第三部分*号表示任何类下的任何方法
第四部分(..)表示任意参数个数
通知(Advice): 在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。Spring中定义了四个advice: BeforeAdvice, AfterAdvice, ThrowAdvice和DynamicIntroductionAdvice
目标对象(Target ): 包含连接点的对象。也被称作被通知或被代理对象。POJO
织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
AOP实现方式
1.注解实现
先要对xml的文件进行设置扫描基础包,同时要设置 <aop:aspectj-autoproxy>否则注解不产生效果
<context:component-scan base-package="com.cqucc" /><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
创建类,书写里面的方法并交给Spring管理
import com.cqucc.pojo.User;
import org.springframework.stereotype.Repository;@Repository
public class UserDao {public void save(){System.out.println("userdao中实现了1的save");}public void update(User user){System.out.println("dao中实现了1的" + user);try {System.out.println(1/0);}catch (Exception e){System.out.println("异常了");}}
}
创建增强类(增强逻辑)在增强类里面,创建方法,让不同方法代表不同通知类型
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Component
@Aspect
public class UserDaoProxy1 {@Before(value = "execution(* com.cqucc.dao.UserDao.*(..))")public void before(){System.out.println("方法执行之前");}@After(value = "execution(* com.cqucc.dao.UserDao.*(..))")public void after(){System.out.println("在方法执行之后");}@AfterReturning(value = "execution(* com.cqucc.dao.UserDao.*(..))")public void afterReturning(){System.out.println("最终通知");}@AfterThrowing(value = "execution(* com.cqucc.dao.UserDao.*(..))")public void afterthrow(){System.out.println("异常通知");}@Around(value = "execution(* com.cqucc.dao.UserDao.*(..))")public void around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕之前");joinPoint.proceed();System.out.println("环绕之后");}
}
书写测试
@Testpublic void Test1(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserDao bean = context.getBean(UserDao.class);bean.update();}
测试结果
2. 书写Pointcut一个方法对上述代码简化
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Component
@Aspect
public class UserDaoProxy1 {@Pointcut(value = "execution(* com.cqucc.dao.UserDao.*(..))")public void point(){}@Before(value = "point()")public void before(){System.out.println("方法执行之前");}@After(value = "point()")public void after(){System.out.println("在方法执行之后");}@AfterReturning(value = "point()")public void afterReturning(){System.out.println("最终通知");}@AfterThrowing(value = "point()")public void afterthrow(){System.out.println("异常通知");}@Around(value = "point()")public void around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕之前");joinPoint.proceed();System.out.println("环绕之后");}
}
测试方法同上,结果如下
3.通过配置文件实现
配置beans.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"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:c="http://www.springframework.org/schema/c"xmlns:util="http://www.springframework.org/schema/util"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"><context:component-scan base-package="com.cqucc" /><bean class="com.cqucc.dao.proxy.UserDaoProxy" id="userDaoProxy"></bean><aop:config><aop:pointcut id="point" expression="execution(* com.cqucc.dao.UserDao.*(..))"/><aop:aspect ref="userDaoProxy"><aop:before method="before" pointcut-ref="point"></aop:before><aop:after method="after" pointcut-ref="point"></aop:after><aop:after-throwing method="afterthrow" pointcut-ref="point"></aop:after-throwing><aop:after-returning method="afterReturning" pointcut-ref="point"></aop:after-returning><aop:around method="around" pointcut-ref="point"></aop:around></aop:aspect></aop:config>
</beans>
配置了xml文件,增强类就不需要注释了
package com.cqucc.dao.proxy;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;public class UserDaoProxy {public void point(){}public void before(){System.out.println("方法执行之前");}public void after(){System.out.println("在方法执行之后");}public void afterReturning(){System.out.println("最终通知");}public void afterthrow(){System.out.println("异常通知");}public void around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕之前");joinPoint.proceed();System.out.println("环绕之后");}
}
测试结果
Spring整合jdbc
1.配置maven仓库
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.9</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.3.8</version></dependency>
2.添加数据库配置文件
3.使用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"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:c="http://www.springframework.org/schema/c"xmlns:util="http://www.springframework.org/schema/util"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"><context:component-scan base-package="com.cqucc"></context:component-scan><context:property-placeholder location="classpath:db.properties"></context:property-placeholder><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean><bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean>
</beans>
4.创建Cities实体类
package com.cqucc.pojo;public class Cities {private int cid;private String cname;private int pid;public Cities() {}public Cities(String cname, Integer pid) {this.cname = cname;this.pid = pid;}public Cities(Integer cid, String cname, Integer pid) {this.cid = cid;this.cname = cname;this.pid = pid;}public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getCname() {return cname;}public void setCname(String cname) {this.cname = cname;}public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}@Overridepublic String toString() {return "Cities{" +"cid=" + cid +", cname='" + cname + '\'' +", pid=" + pid +'}';}
}
对数据库进行基本操作
1. 添加方法
@Repository
public class CitiesDao {@Autowired//自动注入private JdbcTemplate jdbcTemplate;public int insert(Cities cities){return jdbcTemplate.update("insert into cities values(null,?,?)",cities.getCname(),cities.getPid());}
}
测试方法
@Testpublic void Test2(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");CitiesDao bean = context.getBean(CitiesDao.class);System.out.println(bean.insert(new Cities("重庆",0)));;}
插入数据前数据库
添加数据后数据库
2.删除方法
import com.cqucc.pojo.Cities;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public class CitiesDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public int delete(int cid){return jdbcTemplate.update("delete from cities where cid=?",cid);}
}
测试方法
@Testpublic void Test4(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");CitiesDao bean = context.getBean(CitiesDao.class);bean.delete(23);}
删除数据后数据库
3.批量查询数据
import com.cqucc.pojo.Cities;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public class CitiesDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public List<Cities> selectAll(){return jdbcTemplate.query("select * from cities where pidlike ?",new BeanPropertyRowMapper<Cities>(Cities.class),1);}
}
测试方法
@Testpublic void Test5(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");CitiesDao bean = context.getBean(CitiesDao.class);List<Cities> cities = bean.selectAll();System.out.println(cities.size());for (Cities c:cities){System.out.println(c);}}
测试结果
4.批量插入数据
import com.cqucc.pojo.Cities;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public class CitiesDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public int[] inserts(List<Object[]> objects){return jdbcTemplate.batchUpdate("insert into cities values(null,?,?)",objects);}
}
测试方法
@Testpublic void Test7(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");CitiesDao bean = context.getBean(CitiesDao.class);List<Object[]> list = new ArrayList<>();Object[] c1 = {"重庆",9};Object[] c2 = {"重庆1",98};Object[] c3 = {"重庆2",98};Object[] c4 = {"重庆3",98};list.add(c1);list.add(c2);list.add(c3);list.add(c4);bean.inserts(list);}
测试结果
5.批量删除数据
public int[] delete(List<Object[]> objects){return jdbcTemplate.batchUpdate("delete from cities where pid=?",objects);}
测试方法
@Testpublic void Test8(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");CitiesDao bean = context.getBean(CitiesDao.class);List<Object[]> list = new ArrayList<>();Object[] c1 = {9};Object[] c2 = {98};Object[] c3 = {98};Object[] c4 = {98};list.add(c1);list.add(c2);list.add(c3);list.add(c4);bean.delete(list);}
测试结果
Spring-Aop及jdbc总结相关推荐
- 使用spring aop实现业务层mysql 读写分离
2019独角兽企业重金招聘Python工程师标准>>> 1.使用spring aop 拦截机制现数据源的动态选取. import java.lang.annotation.Eleme ...
- spring aop原理_Spring知识点总结!已整理成142页离线文档(源码笔记+思维导图)...
写在前面 由于Spring家族的东西很多,一次性写完也不太现实.所以这一次先更新Spring[最核心]的知识点:AOP和IOC 无论是入门还是面试,理解AOP和IOC都是非常重要的.在面试的时候,我没 ...
- java 自定义异常 未回滚_抛出自定义异常,spring AOP事务不回滚的解决方案
spring AOP 默认对RuntimeException()异常或是其子类进行事务回滚,也就是说 事务回滚:throw new RuntimeException("xxxxxxxxxxx ...
- Spring JDBC-实施Spring AOP事务注意事项及案例分析
实施SpringAOP事务注意事项 基于接口动态代理的AOP事务增强 基于CGLib字节码动态代理的AOP事务增强 示例 特别说明 示例源码 实施SpringAOP事务注意事项 众所周知,Spring ...
- Spring - Java/J2EE Application Framework 应用框架 第 5 章 Spring AOP: Spring之面向方面编程G
第 5 章 Spring AOP: Spring之面向方面编程 5.1. 概念 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层 ...
- Spring - Java/J2EE Application Framework 应用框架 第 5 章 Spring AOP: Spring之面向方面编程
第 5 章 Spring AOP: Spring之面向方面编程 5.1. 概念 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层 ...
- 简单好用!利用Spring AOP技术10分钟实现一个读写分离方案
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 作者 ...
- spring aop实例讲解_小实例理解Spring中的AOP----面向切面编程
关于面向切面编程(Spring AOP),是在java面试中经常提及的,只有在充分理解了,日常工作中才能得心应手. 如何理解AOP呢?首先我们要思考为什么要使用切面编程,如下图: 对于一个系统来说保存 ...
- Spring AOP根据JdbcTemplate方法名动态设置数据源
2019独角兽企业重金招聘Python工程师标准>>> 说明:现在的场景是,采用数据库(Mysql)复制(binlog)的方式在两台不同服务器部署并配置主从(Master-Slave ...
- Spring AOP之四:利用AOP实现动态数据源切换
2019独角兽企业重金招聘Python工程师标准>>> 简介和依赖 项目的前提是安装了MySQL数据库,并且建立了2个数据库一个是master,一个是slave,并且这2个数据库都有 ...
最新文章
- 回顾2020,我国无人机经历了四大新变化
- docker 安装redis第三方集群方案 codis
- NLP之CRF分词训练(六)
- 添加tomcat7插件设置jdk编译版本
- 计算机初试占比高的学校,复试压力小,初试占比70%及以上的院校汇总!
- hbase shell基础和常用命令详解
- DirectInput手柄在Windows环境下震动实现
- 生物信息学常用数据库
- 华为服务器系统图标,华为云 服务器图标 visio
- 从python爬虫以及数据可视化的角度来为大家呈现“227事件”后,肖战粉丝的数据图
- 计算机体系结构实验三 指令调度和延迟分支
- 关于注册时验证邮箱,并实现类似安卓的吐丝效果
- Altium Designer系列:添加泪滴
- STM32L4系列单片机ADC通过内部参考电压精确计算输入电压
- 思科 计算机网络 第十章测试考试答案
- Notion数字笔记使用教程
- JSP语言做简易留言板
- html投票,基于js实现投票的实例代码
- 表格中编辑后进行数据比较的方法介绍-比较两套数据
- css精灵列表使用实例,介绍一个导出CSS精灵图动画的AE小脚本
热门文章
- 军团的崛起:利用多态指挥多兵种作战
- 最大化印刷MES管理系统价值,提升印刷车间效率与质量
- springboot:运行(部署)时出现WebServerException: Unable to create tempDir.
- qq飞车手游微信24区服务器,QQ飞车手游手游开服表_QQ飞车手游手游开服时间表_新服新区预告_第一手游网...
- Python用PIL获取图片信息
- 一键禁用Win10自动更新,联想官方出品!!
- Linux服务器键盘鼠标插口,关于Linux下鼠标键盘
- windows10升级助手_Win7即将全面停更,看这里,决定回退还是升级?
- QT5实现职工工资信息管理系统(文件读写)
- Python爬虫——使用三种方法来爬取酷狗音乐的TOP榜