IOC(DI)&&AOP

版权声明:未经同意,请勿转载!!! https://blog.csdn.net/kyy_123/article/details/80951971

一、IOC(inverse of Control--控制反转)

IOC是OOP思想中的一种设计原则,也是Spring的核心。在处理一个业务需求的时候,会涉及到多个业务层之间的关联。此时需要使用IOC思想,这样可以大大降低程序与类之间的耦合度。

IOC的注入方式有两种:依赖注入和依赖查找。

(1)依赖注入(DI--Dependency Injection):应用程序被动地接收对象,容器通过类型或名称等判断将不同的对象注入对应的属性中。

依赖注入的方式:

    1)set方法:实现特定属性的public setXXX()方法,让IOC容器调用,然后注入所依赖类型的对象;

    2)接口:实现特定接口以供容器注入所依赖类型的对象;

    3)构造函数:实现特定参数的构造函数,创建对象时让容器注入所依赖类型的对象;

    4)注解:Java的注解,例如spring的@Autowired。

(2)依赖查找:相对较为主动地一种方式。在需要参数的时候,会调用框架提供的方法获取对象,只需要提供有关的配置文件路径、key等信息确定可以获取对象的状态。(并不常用)

(3)IOC思想

传统开发中,我们会通过程序自己对创建的依赖进行管理;IOC思想则是利用第三方容器管理并维护一些被依赖的对象(pojo类中的pojo属性,即被依赖对象),应用程序只需要接收并使用这些对象即可,无需关注其他事情。

总结:控制反转就是将对象控制权进行了转移,应用程序将其转交给第三方容器,并让它们进行管理这些被依赖对象,完成了应用程序与被依赖对象之间的解耦合。

举例说明:某天你在家口渴了,需要喝水,家里没有水,所以你需要去小卖部买水。整个过程就是你到小卖部告诉他们你需要水,然后老板将水给你。但是,这之前你需要考虑小卖部是否很远,是否需要开车或者小卖部里是否有水等。买水很简单的事情,但是这些事情让它变得复杂。

其实,很简单的解决方法——小卖部提供外送服务,你打电话告诉卖部老板,他们给你送水到家。这样你做的事情就是:

(1)向小卖部注册会员;(2)告诉小卖部你需要什么。

spring中的IOC思想与之类似:小卖部就是Spring ,你就是A对象,水就是B对象。这时候需要做的只有两步:

(1)在Spring中注入一个类A;(2)告诉Spring,A需要B

假设A是UserAction类,而B是UserService类
<bean id="userService" class="org.leadfar.service.UserService"/>
<bean id="documentService" class="org.leadfar.service.DocumentService"/>
<bean id="orgService" class="org.leadfar.service.OrgService"/>
 
<bean id="userAction" class="org.leadfar.web.UserAction">
     <property name="userService" ref="userService"/>
</bean>
在Spring这个商店(工厂)中,有很多对象/服务:userService,documentService,orgService,
也有很多会员:userAction等等,声明userAction需要userService即可,
Spring将通过你给它提供的通道主动把userService送上门来,因此UserAction的代码示例类似如下所示:
    package org.leadfar.web;
    public class UserAction{
         private UserService userService;
         public String login(){
              userService.valifyUser(xxx);
         }
         public void setUserService(UserService userService){
              this.userService = userService;
         }
    }
 在这段代码里面,你无需自己创建UserService对象
(Spring作为背后无形的手,把UserService对象通过你定义的setUserService()方法把它主动送给了你,这就叫依赖注入!)
当然咯,我们也可以使用注解来注入。Spring依赖注入的实现技术是:动态代理

二、AOP(面向切面编程--Aspect-Oriented Programming)

AOP是一种在运行时,能够动态将代码切入到类的指定方法、指定位置的编程思想。包含两部分:切面--用于切入到指定类的指定方法的代码片段;切点--切入到指定类的某个指定方法。

AOP是OOP的有利补充。OOP从横向上区分出一个个的类,而AOP则从纵向上为指定类的指定方法动态切入代码,这样使得OOP更为立体。

Java中的JDK动态代理和CGLIB均是AOP的体现。

假设我们需要在执行业务逻辑之后输出它的日志信息,这样我们可以在每一个类中定义一个recordLog方法,但是这样子代码的冗余度太高。我们也可以将输出日志的方法抽取出来,重新定义一个新类,然后在每个类中调用该类的方法,但是这样又会造成类与类之间的高耦合。所以此时AOP思想的优点就会比较突出。

使用AOP思想,将recordLog方法定义成一个aspectJ中的方法(即切入点),然后动态地将该方法注入到指定类的指定方法中,既解决了代码冗余,又降低类之间的耦合度。

我们使用AspectJ,它是一个AOP框架,扩展了Java语言,并定义了AOP语法(通过它实现的编译器).
使用AspectJ需要先安装并将lib中aspectjrt.jar添加进入classpath,下载地址.
public class Something { public void say() { System.out.println("Say something..."); } public static void main(String[] args) { Something something = new Something(); something.say(); }}public aspect SomethingAspect { /** * 切入点,切入到Something.say() */ pointcut recordLog():call(* com.sun.sylvanas.application.hello_aop.Something.say(..)); /** * 在方法执行后执行 */ after():recordLog() { System.out.println("[AFTER] Record log..."); }}

举例说明:AOP的目的在于分离关注点(即必须要做的事)。例如:你是一个富家公子,衣来伸手,饭来张口,每天只有一件事需要你做)玩。但是,玩之前,你还需要穿衣服、收拾房间等,而这些事情就是你的关注点,然而你并不想干这些事。所以这时候你就可以将这些事情统统交由他人去干。当你吃饭之前,A帮你穿衣服,B帮你叠被子,这样你就可以直接吃饭然后玩。玩完再由AB帮你干其他的事情。所以你这一天就只干了你必须要做的事,而没有关注其他的事情。如果某天你想自己穿衣服,那么你只需要将A辞掉即可。所以这就是AOP,每个人有每个人的事情,互不干扰,灵活配合,形成一种可配置、可插拔的程序结构。

从Spring上考虑,AOP最大的好处在于提供事务管理的能力。即你只需要访问数据库,而不需要管理事务(关注点),所以AOP就可以在你访问数据库之前,开启事务;访问完之后,再自动提交/回滚事务。


猜你喜欢

转载自blog.csdn.net/kyy_123/article/details/80951971