文章目录

  • 前言
  • 一、Spring框架中的核心思想?
    • 1.1依赖注入(DI)
    • 【总结】IOC DI
  • 二、Spring-面向切面编程(AOP)
    • 2.1代理模式举例
    • 2.2如何开发一个代理对象?
    • 2.2.1 静态代理对象
    • 2.2.2动态代理对象
    • 2.3面向切面编程
    • 2.3.1Spring aop 编程的编程步骤
    • 2.3.2aop编程举例
    • 2.4总结
  • 三、如何用Spring创建复杂对象?
    • 3.1Spring工厂获取对象的原理(回顾)

前言


一、Spring框架中的核心思想?

两个思想:控制反转(IoC, Inversion of Control) 、 面向切面编程(AOP, )

IoC
定义:控制反转:控制权力的反转。
解释:将原来手动通过new关键字创建对象的权力交给了Spring,通过在配置文件中配置bean标签的形式创建对象,交给Spring 由Spring创建对象的过程。

可是,像Tomcat容器,也能够做到不需要new关键字,就可以使用Servlet,(其实背后就是控制反转)。那么控制反转并不是Spring所特有的特性。
因此,Spring在基于IOC基础上,提出了“依赖注入”(DI,Dependency Injection)。

我们可以发现Service层经常需要调用DAO层,即需要DAO组件对象, 这种 “需要” 可以称为 “依赖”,即 依赖DAO组件。

因为DAO组件对象已经在Spring中生成了,那么下次Service层在调用时,只需要在Spring容器中取就好了。

像此时,deptDAO只是有声明,如果需要时在12行直接调用save(),会报空指针异常。
那么 第一步 需要谁。就先声明谁为成员变量,
第二步:为成员变量赋值,为成员变量赋值的过程 ,就称为依赖注入。

1.1依赖注入(DI)

定义:为组件中成员变量完成赋值过程 ,这个过程就称之为 依赖注入。
语法:
1.组件对象中需要哪个组件, 就将谁声明为成员变量 并提供公开的SET方法。(示例如下:)
(提供get方法,会出现代码冗余)

只有上面操作还不够,还要经过第二步
2.在Spring的配置文件中对应的 组件标签内 完成属性的赋值操作。
下面就是依赖注入的示例:


以上就是依赖注入的过程。
并且可以总结得知:通过IOC可以创建组件对象, 通过DI 维护了组件与组件之间的调用关系
此时
IOC的全部定义概述为:

即控制反转, 将原来手动通过new关键字创建对象的权力交给Spring,由Spring工厂创建对象的过程。
当然,Spring不仅创建对象还要再创建对象的同时,通过DI的方式维护组件与组件的调用关系。

DI(set方式注入)基本语法:
DAO层:

Service层:

配置文件的赋值:


启动工厂测试:

其实在Spring中注入方式主要有三种:
(重点)a.SET注入 : 使用成员变量SET方法形式进行赋值
(了解)b.构造注入 : 使用构造方法形式 进行属性的赋值
(了解)c.自动注入 : 通过在配置文件中 完成类中属性自动赋值

Spring中SET方法的注入语法:
上面已经讲过的,注入时,把组件对象声明,然后生成SET方法,
但如果需要注入的不是对象, 而是一个String属性值、Date类型的还和上面的语法一样吗?
可以通过在xml文件中选用value对 八种基本数据类型 + String类型 + Date 类型 统一使用 value属性进行注入



Spring中对日期类型的值注入,只能使用格式为value=“yyyy/MM/dd HH:mm:ss”

总结:


对于Map类型,其键值对,根据具体情况具体写,总体原则是,对象类型就要用ref, String等类型用value。例如:key-ref,value-ref等

对于properties配置文件,里面也是key-value:,里面都是放String,所以没有什么key-ref:

【总结】IOC DI




二、Spring-面向切面编程(AOP)

面向切面的编程,:(AOP,Aspect Oriented Programing )
底层原理:java 代理设计模式 动态代理
好处:在保证 原始业务功能不变的情况下, 通过代理对象完成 业务中附加操作,将业务中核心操作 放在目标对象中执行,实现了附加操作和核心操作的解耦
在说AOP之前,需要先明白代理设计模式
java: (Proxy)代理设计模式

2.1代理模式举例

小张和小丽网恋,小张(业务逻辑调用者,Main())给小丽的账号名(如花)(接口Interface)发消息,本来小丽要给闺蜜做饭,所以就让小丽闺蜜(代理对象Proxy)帮自己打字,并转述聊天内容。在这个过程中小张是不知道手机对面是谁在和自己聊天(接口屏蔽了底层的具体实现逻辑)。
小丽闺蜜的存在,减轻了小丽的负担,保证了原始业务逻辑不变,同时还能使小丽完成一些附加事情。

2.2如何开发一个代理对象?

2.2.1 静态代理对象

a) 代理对象和 业务逻辑对象 (真正的业务逻辑对象) 实现相同的接口
b) 代理对象中 依赖 真正业务逻辑对象
先看看原始业务逻辑对象的代码:存在大量冗余(忙)

以上代码可以看到,每个方法都出现了大量的代码冗余,(开启事务,提交事务…)
有代理的存在和无代理的存在,能完成的原始功能是一致的,但是有代理的话,可以让原始业务逻辑对象更加专注去处理原来的核心业务(处理DAO)。
(静态)代理对象的代码:

spring.xml中:

因此有了代理存在,就 不能再调用原始的业务逻辑对象,而是 应该调用代理对象,才能保证原始大的功能不变。


上面讲的,为每一个业务层 通过手动开发一个代理对象的过程 称之为 “静态代理对象”

存在问题:很明显,静态代理开发,比原先更加复杂了,(需要多写一个类),如果为每一个业务层开发一个静态代理类,不仅没有减轻工作量,
甚至让工作量多了一倍。
解决方案:为业务层在运行过程中动态创建代理类,通过动态代理类去解决现有业务层中业务代码冗余问题。

2.2.2动态代理对象

代理对象:保证原始功能不变的情况下,完成业务逻辑中附加操作
原始业务逻辑对象:也叫Target,目标对象| 被代理对象称之为目标对象, 原始业务逻辑对象
什么是动态代理:
在程序运行过程中,通过代码底层的方式,为指定的类创建动态代理对象,(不是手工开发的,是根据接口创建的)

proxy 用来生成动态对象的类
参数1:classLoader 类加载器
参数2:Class[] 目标对象的接口的类型的数组 (一个类可以实现多个接口,所以是数组)
参数3: InvocationHandler 接口类型 invoke 方法用来书写额外功能(附加操作)

UserService userService = new UserServiceImpl(); //目标类
//类加载器,
ClassLoader classLoader = Thread.currentThread().getContextClassLoader()
//Class[] 目标对象的接口 的类型 的数组
Class[] classes = {UserService.class};
//返回值:创建好的动态代理对象:
//(为目标类创建代理对象,方式是,通过底层的classLoader类加载器,
//读到UserServiceImpl的类信息,把信息加载到内存中,然后才能对应生成动态代理)
Uservice userServiceDynamicProxy = (UserService)Proxy.newProxyInstancce(classLoader, classes,new InvocationHandler(){//通过动态代理对象调用自己里面代理方法时 会优先指定InvocationHandler类中invoke方法@Override
//参数1:当前创建好的代理对象; 参数2:当前代理对象执行的方法对象, 参数3:当前代理对象执行方法的参数public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{System.outprintln("当前执行的方法:"+method.getName());System.outprintln("当前执行的方法的参数:"+args[0]);try{System.outprintln("开启事务");//调用目标类中业务方法,通过反射机制,调用目标类中当前方法Object invoke = method.invoke(new UserServiceImpl(), args)System.outprintln("提交事务");return invoke;}catch(Exception e){e.printStackTrace();System.out.println("回滚事务");}return null;}});
String name =proxy.findAll("小明");    //通过动态代理对象调用代理中的方法,执行这里时,会跳到上面执行@Override的方法

第一个参数是类加载器,为什么呢?
读接口的信息,底层操作字节码,读字节码 动态生成对象,classLoader就是用来读class文件,读类信息的
classes,告诉基于哪个目标类的接口,去生成代理对象

2.3面向切面编程

下图方框中标记的代码,我们称为附加操作,附加操作在AOP中被称为通知(Advice)
通知(Advice):除了目标方法以外的操作都称之为通知 附加功能 事务通知 日志通知 性能通知…
切入点(Pointcut): 指定开发好的 通知 应用于项目中 哪些组件中 哪些方法,通常通知多用于业务层
切面(Aspect):通知(Advice) + 切入点 (pointcut)

环绕通知:围绕目标方法执行的通知

AOP 面向切面编程:
1.开发通知类(附加功能)
2.配置切面点
3.组装切面(Aspect)

2.3.1Spring aop 编程的编程步骤

1.引入aop编程相关依赖

spring-aop、 spring-expression 、spring-aspect

2.项目开发额外功能通知

环绕通知 MethodIntercept
前置通知 MethodforAdvice
后置通知 AfterReturningAdvice
异常通知 ThrowsAdvice

3.配置切面 (在spring.xml中完成)
a).注册通知类

<bean id ="" class="xxxAdvice">

b).组装切面 aspect = advice + pointcut

<aop:config><aop:pointcut id="" expression="execution()"/><aop:advisor advice-ref="" pointcut-ref=""/>
</aop:config>

2.3.2aop编程举例


上面程序中第8、14行,只是方法名称不同,存在冗余,因此可通过切面编程优化。
解决: 自己写一个前置通知,这个要实现框架中提供的接口 (implements MethodBeforeAdvice)


上述代码中,expression="execution(* aop.EmpServiceImpl.*(..))"
第一个*代表 可 任意类型的返回值
第二个 参数 aop.EmpServiceImpl.*(..)这个包名 表示 切入点在 aop.EmpServiceImpl类下的所有方法。如果写成aop.*ServiceImpl.*.(..)则表示,切入点在aop包下的所有以ServiceImpl结尾的类,都会切入切面。

上述在spring.xml中配置的代码,只要发现了有<aop.advisor>,那么就会根据该句中的pointcut-ref=""/>生成动态代理对象,

2.4总结



说明:
在implements MethodBeforeAdvice之后,重写的这个before()已经把InvokHandler中的invoke方法做了提取,提取成了 各种各样的通知,

这才使得,当只要切入成功,这里通过getBean得到的empService对象变成了代理对象, 它会优先执行代理对象的方法。然后再调用dao执行业务逻辑方法

三、如何用Spring创建复杂对象?

3.1Spring工厂获取对象的原理(回顾)


为什么经过上面的a)b)c)三步,工厂可以获取到组件对象?
因为是反射机制
通过Class.forName("全限定名"),读取类的信息,然后又调用 newInstance()调用类的构造方法进行对象的创建

3.通过工厂创建简单对象
简单对象:可以直接通过new关键字 创建的对象 ,统一称为 简单对象
工厂创建简单对象时直接通过<bean id="xxx" class="xxx">完成

4.通过工厂创建复杂对象
复杂对象: 不能直接通过new关键字进行创建对象,例如:接口类型 | Collection | 抽象类类型 Calender(日历)/ MessageDigest(加密)…

对象名FactoryBean  implements  FactoryBean<Calender|Connection|复杂对象>{}
例如:创建Calender复杂对象,1) implements+ 2) @override
public class CalenderFactoryBean implements FactoryBean<Calender> {//用来书写复杂对象的创建方式@Overridepublic Calender getObject() throws Exception{return Calender.getInstance();}//指定创建的复杂对象的类型@Overridepublic Class<?> getObjectType(){return Calender.class;}//用来指定创建的对象模式,单例或多例@Overridepublic boolean isSingleton(){return false;}
}

工厂创建日历(复杂)对象:

工厂创建连接对象:

在工厂中获取复杂对象的方式也是用<bean>

代码如下(示例):

【Spring】IoC,DI,两种代理方式,AOP定义和使用相关推荐

  1. Spring的两种代理方式:JDK动态代理和CGLIB动态代理

    代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为"代理",所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者 ...

  2. Spring与Hibernate两种组合方式

    Spring与Hibernate大致有两种组合方式,主要区别是一种是在Hibernate中的hibernate.cfg.xml中配置数据源,一种是借助Spring的jdbc方式在Spring的appl ...

  3. Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)

    第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation ...

  4. 【Spring AOP(2)篇】原理及两种实现方式(cglibjdk动态代理)

    简介: Spring AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 框架的一个重要特性,用于解耦和切割业务逻辑,是实现面向切面编程的重要手段之一.本文 ...

  5. Spring AOP两种使用方式以及如何使用解析

    AOP是一种面向切面编程思想,也是面向对象设计(OOP)的一种延伸. 在Spring实现AOP有两种实现方式,一种是采用JDK动态代理实现,另外一种就是采用CGLIB代理实现,Spring是如何实现的 ...

  6. Java框架篇---spring aop两种配置方式

    Java框架篇---spring aop两种配置方式 第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步:  1. 使用注解@Aspect来定义一个切面,在切面中 ...

  7. java动态代理两种实现方式

    代理顾名思义就是代理别人完成某件任务,比如张三代理李四去交物业费.张三就是代理人,李四就是被代理人. Java代理实现,有静态代理和动态代理,静态代理就是代码在编译成class文件后,就已经有代理类的 ...

  8. 【IOC 控制反转】IOC 简介 ( 依赖注入的两种实现方式 | 编译期注入 | 运行期注入 )

    文章目录 一.IOC 简介 二.依赖注入的两种实现方式 一.IOC 简介 IOC 是 Inversion Of Control 的缩写 , 控制反转 ; 其最主要的作用是 降低代码的耦合度 , 最常见 ...

  9. AOP 详解 、AOP 中通知类型 、AOP 两种实现方式(Schema-base 和 AspectJ)

    一.AOP AOP:中文名称面向切面编程 英文名称:(Aspect Oriented Programming) 正常程序执行流程都是纵向执行流程 3.1 又叫面向切面编程,在原有纵向执行流程中添加横切 ...

  10. spring入门之Spring 常用的三种注入方式

    Spring 常用的三种注入方式 Spring 通过 DI(依赖注入)实现 IOC(控制反转),常用的注入方式主要有三种:构造方法注入,set 方法注入,基于注解的注入. 一.通过构造方法注入 先简单 ...

最新文章

  1. C++中typedef和define的区别
  2. 一文带你了解卷积神经网络基础,建议收藏
  3. UIBezierPath 绘制正五边形
  4. Linux df -h查看磁盘使用情况
  5. MongoDB查询性能分析—— explain 操作返回结果详解
  6. linux c计算两个int相除求百分比的实现
  7. 命令行运行Jmeter实例
  8. java html转word!
  9. NYOJ 412 Same binary weight题解
  10. 网名接龙--之追求完美
  11. 【洛谷】洛谷深基学习记录 第二章 顺序结构程序设计
  12. 如何扩大计算机的硬盘空间,Win7系统怎么扩大C盘空间 Win7电脑扩大硬盘C盘空间方法介绍...
  13. 用Canvas画一个七巧板
  14. Qter 开发资源大集合
  15. 2021 || You Cannot Easily Catch Me: A Low-Detectable Adversarial Patch for Object Detectors
  16. 分时系统和实时系统(操作系统)
  17. SSL/TLS类安全漏洞及SLB安全漏洞问题
  18. cnn卷积神经网络手写体识别keras和tensorflow
  19. (附源码)Springboot小程序交通违法举报系统 毕业设计 242045
  20. Windows Media Player控件属性及方法(c#)以duration为什么总是“0”解决方法

热门文章

  1. linux关闭云锁服务器,安全软件之linux系统下云锁简单的安装方法
  2. 虚幻4引擎源码学习笔记(二):主循环LaunchEngineLoop
  3. 【转】腾讯云PCDN:从P2P到万物互联服务框架
  4. 从零开始 CMake 学习笔记 (G)compile-flags
  5. ORACLE数据库字段类型说明
  6. 亲手制作:超级DOS工具+Vista+加强版WindowsXP Lite5.8集成
  7. layui爬坑之路——input value属性绑定函数返回值
  8. 【opencv】颜色空间总结
  9. 2020幻影围棋 第三天围棋规则模块(一)
  10. web安全主要包括哪些方面的安全