秒杀P3-IOC、AOP

116 阅读5分钟

springmvc基于spring。 项目创建演示:

视图层

controller包下controller类用到的注解

@controller controller层注解,让bean受容器管理让前端可以访问类?

@Requestmapping 声明前端访问类的路径

@Requestmapping 声明前端访问方法的路径,和方法处理请求的类型,get方法。

@requestbody 声明返回值的类型,字符串。

  image.png

构建项目很快:Springboot 的xml文件中,引入一个starter-web的包,就可以自动装备各种依赖。

  image.png

数据层——代码跟数据库交互

帮我们创建对象,管理对象关系,便于项目的可插拔。

DAO包:数据访问层

包下创建Userdao接口声明接口方法,getById(),根据id查询user,返回user对象。里面调用了user类

此时还没有user,要写实体类

image.png

Entity包:实体类

包下创建user类。声明user对象/类,及user的属性、getset方法。

再回dao接口中,引入user

image.png

impl包:实现类

包下创建userdaojdbcimpl实现类。dao接口的实现类重写接口方法,实现具体的内容。

userdaojdbcimpl类上加 **@repository** 使bean(接口的实例)受容器管理

image.png

业务层

service包:

包下创建userservice接口。接口内声明方法,getUser()。

image.png

创建serviceimpl包,包下创建userserviceimpl实现类(对象/bean)。类实现service接口。

userserviceimpl类要调用userdao对象。业务层方法要查数据库,调用dao(对象)层的代码。

Ioc的思想:容器把dao对象注入进来。通过容器自动装配对象。

方式:声明userdao接口,上方加**@Autowired**注解。相对应的bean(实现类)会自动装填进来。

前提:serviceimpl这个bean需要容器管理

加注解**@service**

image.png

测试代码:

image.png

总结

三个注解功能一样,语义差别:

  • @controller:controller层注解,让bean受容器管理

  • @repository:dao层注解,在接口的impl实现类上加使,bean/对象/接口实例,受容器管理。

  • @service:service业务层注解,在接口的impl实现类上加使,bean/对象/接口实例,受容器管理。

  • @component:公用bean注解

@Autowired

依赖注入。要调什么bean,就注入什么接口的依赖。

我们依赖接口,具体调用什么对应的bean,由对spring管理

impl实现类(bean),实现(原始)接口,重写接口的方法。

一个类中,需要哪个bean就可以用@autowired注入进来,前提是bean有加受容器管理的注解。

数据交互:前端————controller————service————dao

IOC如何实现可插拔

其他不动,只需要新建一个业务层的,新的dao的impl实现类、加@repository注解,原dao的impl去掉@repository注解。此时有两个类,但容器只会管理新的,有@repository的bean/类。

很少这么做。

Ioc:

控制反转/依赖注入:把对bean的管理权利,交给spring来做。获得依赖对象的过程由自身管理变为了由IOC容器注入,可以降低程序的bean之间的耦合度。

service和dao是单例的,复用性强的,只需要实例化一次,用ioc(容器)管理。

user对象每个不同,就不能用。

开发什么(用户)模块就加什么controller(usercontroller)

service和dao有实现类,controller没有。

controller由页面调用,没有接口。

管理生命周期

在xxxservic的实现类serviceimpl中,用以下两个注解管理。 Postconstruct注解,在创建对象后,进行什么操作。通常用init()方法

predestory注解,在对象清除之前的操作。通常用destroy()

image.png

spring对象bean默认是单例的,

  • scope注解,管理bean作用域,默认是singleton单例,可不加括号不写

  • prototype注解,每次请求都会创建bean,多例

image.png

IOC

通过beanfactory(上层接口)+ applicationcontext(底层接口,bean的工厂,核心功能获取bean)两子接口管理。

开发者多用applicationcontext,功能更强。beanfactory算是内部接口spring开发者用

applicationcontext继承beanfactory

IOC底层原理

@springboottest高级注解,表示test文件受容器管理。

当类继承(实现)applicationcontextaware接口时。里面set方法,会把applicationcontext容器本身装配到bean中。则可以用applicationcontext.getbean(参数可以是类型,名字)获取bean。

image.png

获取bean示例。

userdao.class类型,userxxximpl 对象名字

image.png

spring自动配置过程

image.png

AOP

面向切面编程——针对很多bean共同的批量需求,统一处理,且无需对这些bean做改动

统一记日志,统一事务等。

如:现在要处理日志。

新建logaspect类,加入@aspect注解。(需要在pom.xml中配置依赖)

image.png

概念

  • target:目标组件——要处理的对象bean
  • joinpoint:连接点——要处理的方法
  • aspect:切面组件——标识@aspect注解的公共类,具有特殊含义
  • pointcut:切点——表示要处理哪些组件(组件)、方法
  • advice:通知——表示在处理目标bean前或后执行xxx
    • before/after

image.png

操作

  1. 建aspect类
  2. 加@component表示公共bean受容器管理
  3. 加@aspect注解表示切面组件,要对一批bean处理
  4. 建切点方法,加@pointcut注解,后加括号,用execution公式标注要处理哪些方法/类
  5. 建通知方法【怎么处理这批bean的内容】,加@Before(运行目标方法前)@AfterThrowing(目标方法运行抛出异常后)@AfterReturning(运行目标方法后)@After(方法运行结束后,始终会运行,final)注解,后加括号,写入切点方法,表示关联的切点。

流程如下:

image.png

image.png

运行结果:

image.png

select with hibernate 表示get方法运行成功的

关键:织入

底层不是执行真正的service,而是代理service。把aspect代码插入到代理类里执行。

@Around注解,前后都有操作

返回object,参数是(ProceedingJoinPoint joinPoint)

obj = joinPoint.proceed();功能是调用目标组件的方法

image.png