什么是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总结相关推荐

  1. 使用spring aop实现业务层mysql 读写分离

    2019独角兽企业重金招聘Python工程师标准>>> 1.使用spring aop 拦截机制现数据源的动态选取. import java.lang.annotation.Eleme ...

  2. spring aop原理_Spring知识点总结!已整理成142页离线文档(源码笔记+思维导图)...

    写在前面 由于Spring家族的东西很多,一次性写完也不太现实.所以这一次先更新Spring[最核心]的知识点:AOP和IOC 无论是入门还是面试,理解AOP和IOC都是非常重要的.在面试的时候,我没 ...

  3. java 自定义异常 未回滚_抛出自定义异常,spring AOP事务不回滚的解决方案

    spring AOP 默认对RuntimeException()异常或是其子类进行事务回滚,也就是说 事务回滚:throw new RuntimeException("xxxxxxxxxxx ...

  4. Spring JDBC-实施Spring AOP事务注意事项及案例分析

    实施SpringAOP事务注意事项 基于接口动态代理的AOP事务增强 基于CGLib字节码动态代理的AOP事务增强 示例 特别说明 示例源码 实施SpringAOP事务注意事项 众所周知,Spring ...

  5. Spring - Java/J2EE Application Framework 应用框架 第 5 章 Spring AOP: Spring之面向方面编程G

    第 5 章 Spring AOP: Spring之面向方面编程 5.1. 概念 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层 ...

  6. Spring - Java/J2EE Application Framework 应用框架 第 5 章 Spring AOP: Spring之面向方面编程

    第 5 章 Spring AOP: Spring之面向方面编程 5.1. 概念 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层 ...

  7. 简单好用!利用Spring AOP技术10分钟实现一个读写分离方案

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 作者 ...

  8. spring aop实例讲解_小实例理解Spring中的AOP----面向切面编程

    关于面向切面编程(Spring AOP),是在java面试中经常提及的,只有在充分理解了,日常工作中才能得心应手. 如何理解AOP呢?首先我们要思考为什么要使用切面编程,如下图: 对于一个系统来说保存 ...

  9. Spring AOP根据JdbcTemplate方法名动态设置数据源

    2019独角兽企业重金招聘Python工程师标准>>> 说明:现在的场景是,采用数据库(Mysql)复制(binlog)的方式在两台不同服务器部署并配置主从(Master-Slave ...

  10. Spring AOP之四:利用AOP实现动态数据源切换

    2019独角兽企业重金招聘Python工程师标准>>> 简介和依赖 项目的前提是安装了MySQL数据库,并且建立了2个数据库一个是master,一个是slave,并且这2个数据库都有 ...

最新文章

  1. 回顾2020,我国无人机经历了四大新变化
  2. docker 安装redis第三方集群方案 codis
  3. NLP之CRF分词训练(六)
  4. 添加tomcat7插件设置jdk编译版本
  5. 计算机初试占比高的学校,复试压力小,初试占比70%及以上的院校汇总!
  6. hbase shell基础和常用命令详解
  7. DirectInput手柄在Windows环境下震动实现
  8. 生物信息学常用数据库
  9. 华为服务器系统图标,华为云 服务器图标 visio
  10. 从python爬虫以及数据可视化的角度来为大家呈现“227事件”后,肖战粉丝的数据图
  11. 计算机体系结构实验三 指令调度和延迟分支
  12. 关于注册时验证邮箱,并实现类似安卓的吐丝效果
  13. Altium Designer系列:添加泪滴
  14. STM32L4系列单片机ADC通过内部参考电压精确计算输入电压
  15. 思科 计算机网络 第十章测试考试答案
  16. Notion数字笔记使用教程
  17. JSP语言做简易留言板
  18. html投票,基于js实现投票的实例代码
  19. 表格中编辑后进行数据比较的方法介绍-比较两套数据
  20. css精灵列表使用实例,介绍一个导出CSS精灵图动画的AE小脚本

热门文章

  1. 军团的崛起:利用多态指挥多兵种作战
  2. 最大化印刷MES管理系统价值,提升印刷车间效率与质量
  3. springboot:运行(部署)时出现WebServerException: Unable to create tempDir.
  4. qq飞车手游微信24区服务器,QQ飞车手游手游开服表_QQ飞车手游手游开服时间表_新服新区预告_第一手游网...
  5. Python用PIL获取图片信息
  6. 一键禁用Win10自动更新,联想官方出品!!
  7. Linux服务器键盘鼠标插口,关于Linux下鼠标键盘
  8. windows10升级助手_Win7即将全面停更,看这里,决定回退还是升级?
  9. QT5实现职工工资信息管理系统(文件读写)
  10. Python爬虫——使用三种方法来爬取酷狗音乐的TOP榜