Spring框架简略描述
Spring中两大体系结构分别是控制反转IOC以及面向切面AOP
Spring框架很好诠释了面向对象法则中的高内聚,低耦合的特性。其中高内聚则体现在AOP中,低耦合在体现在IOC中。
控制反转是指对实例化对象的控制权由传统的类主动创建实例变成了类被动的获取实例。在传统的Java编程中,一个类如果想要获取另外一个类的实例,必然是通过在本类的内部通过new关键字来实例化另外一个类,这样导致了类与类之间的依赖性极强,耦合性极高。而在Spring框架中我们通过构造一个Spring容器(applicationContext.xml)来对其他类的实例进行创建和管理,当有变量需要某一个类的实例时,直接从Spring容器中获取就可以了,这样就能够有效的降低类和类之间的耦合性。
在Spring容器中实例化类的方式有四种
以下操作都是基于applicationContext.xml配置文件进行(除非Java代码)
一:通过无参构造来创建实例
需要注意:对类信息的获取需要有类名以及全路径,如果类内部有有参构造方法则无法实现
二:通过静态工程创建
首先我们需要构造一个静态获取Bean的工厂
然后通过通过工厂中方法获取Bean的实例
注意:一定要加上静态工厂中的方法
三:通过实例工厂获取Bean,同上将静态工厂中static去掉
四:通过FactroyBean创建实例 有兴趣自行百度
以上是将实例注入到Spring容器中,而对类中属性注入值或依赖的方式有两种
一:通过构造器注入
其中的name关键字也可以改为有参构造器中的下标,但顺序要与之对应,用value关键字对属性注入值是普通类型值注入也就是字符串,基本数据类型等,而用ref对属性注入则是针对于复杂类型值的注入,也就是对于其他对象的引用(ref注入值的名称一定要与实例化Bean的名字相对应)
二:通过set方法注入
通过set方法注入的原理是将对象的属性首字母大写,然后在前面加上set方法,以此来和类中的set方法进行对应赋值,所以在对应的实体类中一定要有与之对应的set方法
在其他实体类中获取实例的办法
我们通过Spring容器来对Bean进行实例化后,一定是要去引用这个实例的,引用这个实例我们需要创建一个Spring容器
创建完容器我们就可以通过getBean的方法对容器进行取值
注意:getBean中的参数一定要和Spring容器中实例化Bean的id一致
面向切面编程很好遵循了开闭原则,在不改变原有代码的基础上对程序进行增强、通知。所谓切面是指代理对象和原生对象的结合,我们通过对applicetionContext.xml文件的配置使原生对象运行时,动态的使用代理对象对其进行前置通知、后置通知、环绕通知、抛出通知以及最终通知,这些通知既可以作为对原生对象进行监控,也可以对原生对象进行增强,对用户的权限进行管理,二者相互结合就形成了AOP。
使用面向切面编程我们需要了解一些相关的术语
连接点:JoinPoint 连接点专指对某个方法进行操作,某个方法需要被拦截了,则把该方法成为连接点
切入点:Pointcut 切入点是指对连接点的集合,一般是指对某个类中的所有方法,或者某些类中的所有方法进行拦截
代理对象:
通知/增强:Advice 通知/增强 是指代理类拦截到连接点或者切入点后对对象或者方法进行通知或者增强
一:首先我们需要配置一个对原生对象进行增强的代理类这个代理类中有一系列的前置通知、后置通知、环绕通知等
----------------------------------------------------------------------------------------------------------------------
前置通知:如上图中的第一个方法(采用注解的形式声明其为代理类中的前置通知),因为前置通知在方法前执行,故前置通知不需要有返回值,只需要声明其为前置通知即可
后置通知:如上图中第二个方法,需要有返回值(Object run)返回值需要和切面中的返回值名一致,参数中的JoinPoint指连接点对象,用来获取目标对象信息
环绕通知:需要抛出异常,并且设置ProceedingJoinPoint参数用来控制目标对象执行与否,如果执行目标方法,调用pro.proceed()就可以
抛出通知:如果发生异常抛出异常
最终通知:无论是否发生异常最终通知都会执行,类似finally
------------------------------------------------------------------------------------------------------------
并在xml文件中进行实例化代理类
配置原生类仅为后面方法测试效果做铺垫,不参与配置切面的范围
三:配置切面
图中第二行指
配置切入点范围,并为其设置标志id(配置切入点范围的方式在第一步图中的注解)
第三行值需要为目标对象增强的代理对象
第四行:前置通知
第五行:后置通知 returning对应代理类中的返回值,返回值需要与代理类中的返回值参数名字相同
第六行:环绕通知
第七行:抛出通知 throwing指抛出异常的名字
第八行:最终通知