AOP和IOC



切面是个抽象词,分3个步骤回答。

1.到底是切什么呢?

切方法,把一连串的方法切开。

下面我举例来说明:

1).定义个接口

public interface IAopDemo {
    void eat();

    void work();

    void sleep();
}

2).定义实现类

public class AopDemo implements IAopDemo{
    @Override
    public void eat() {
        System.out.println("eat");
    }

    @Override
    public void work() {
        System.out.println("work");
    }

    @Override
    public void sleep() {
        System.out.println("sleep");
        throw new RuntimeException("exception in sleep Method");
    }
}

3).编写业务逻辑代码

@Test
    public void testAopDemo1() {
        AopDemo aopDemo = new AopDemo();
        aopDemo.eat();
        aopDemo.work();
        aopDemo.sleep();
    }

这里业务逻辑是以此执行三个方法,如果按照aop方式执行这三个方法,也就是将这三个方法切开。试想下,用刀从左到右将代码切为4段

@Test
    public void testAopDemo1() {
        AopDemo aopDemo = new AopDemo();

************************************

aopDemo.eat();

************************************

aopDemo.work();

************************************

aopDemo.sleep();

2.切开做什么?

添加代码

对,就是添加代码,在不影响源代码的前提下添加代码。

3.如何添加代码

添加代码有动态代理和CGLIB的方式来实现,这里我以动态代理为例。

1)代理处理实现类

public class AopDemoHandle implements InvocationHandler {
    private AopDemo aopDemo = new AopDemo();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        Object invoke = null;
        try {
            beforeExecuteMethod(method);
            invoke = method.invoke(aopDemo, args);
            afterExecuteMethod(method);
        } catch (Exception e) {
            executeMethodCaught(e);
        }
        return invoke;
    }

    private void executeMethodCaught(Exception e) {
        System.out.println("execute method happened exception");
    }

    private void afterExecuteMethod(Method method) {
        System.out.println("after execute " + method.getName());
    }

    private void beforeExecuteMethod(Method method) {
        System.out.println("before execute " + method.getName());
    }
}

在方法执行前后,添加处理逻辑代码。

在方法执行异常,添加处理逻辑代码。

2)编写测试案例

@Test
    public void testAopDemo2() {
        IAopDemo aopDemo = (IAopDemo) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{IAopDemo.class}, new AopDemoHandle());
        aopDemo.eat();
        aopDemo.work();
        aopDemo.sleep();
    }

执行结果如下:

before execute eat
eat
after execute eat
before execute work
work
after execute work
before execute sleep
sleep
execute method happened exception

至此,aop编程就实现了。切这个词,侧重于从侧面切,不正面切即从正面修改代码,换个维度,换个方式来修改代码。如果题主不能明白,那就把代码写在纸上,用剪刀剪开,自行体会体会。

aop说白了就是我想改代码,但是想用更优雅的方式来修改。


IOC(Inversion of Control)控制反转模式,意味着去除所有有该类产生但不由该类直接负责的对象实例,而改由外界传入。
由简单的对象开发模式到IOC(控制翻转)
1. 依赖注入(Dependency Injection)
     组件之间的依赖关系有容器在运行时期决定。
2. 控制反转(IoC. Inversion of Control Containers)
     控制权由应用代码中转移到外部容器,控制权的转移。

控制反转模式是当今J2EE架构中常用到的模式之一,它符合好莱坞法则:不要调用我,我会调用你。在没有运用IOC的时候,我们一般都是通过工厂来管理对 象,当我们需要一个对象的时候,我们通过工厂来创建它,这样就造成了业务代码和工厂的耦合,并且更重要的是需要我们自己来管理对象的生命周期,这样非常繁 琐,所以如果我们运用IOC的话,不仅可以解除业务代码与工厂的耦合,而且不用我们进行生命周期管理,大大的减少了编码的工作量。如何实现IOC,现在大 概有以下两种方式: 
     第一:查找实现。此种实现方法需要一个注册表,当我们需要什么对象的时候,我们就去注册表里查找,不需要自己去创建。因为需要的对象是框架或者是容器帮我 们管理的,这时就不需要我们来负责对象的生存周期等的问题。所以生存周期管理也就成了一个容器的必备的能力之一。比如EJB,它就是通过JNDI来查找我 们需要的对象的。这样虽然使得我们不需要管理对象的生命周期,但是同时我们的业务代码还是和具体的注册表API相耦合,所以此种办法没有完全解耦。为了实 现完全的POJO编程模型,需要采用以下的IOC方式(DI)。 
     第二:依赖注射(DI),目前比较流行的是此种实现。依赖注射要求我们只需要声明要用到什么样子的对象,然后设置JavaBean的setter方法就 OK了,在我们需要用到对象的时候,容器会帮助我们把需要的对象设置进来。或者也可以通过有参构造器来进行注射,通过依赖注射,我们的业务代码就不需要与 具体的容器或者是框架耦合,我们可以完全采用POJO的编程模型。因为我们的业务代码没有与任何的容器相耦合,这样就可以使得代码可以在容器内或者容器外 都可以运行,从而提高了复用性和可移植性,同时我们的测试也很容易实现。由此可见IOC给我们的开发带来的是革命性的变化。使得我们的业务代码与具体的容 器的耦合度降到了最低的同时,也给我们的测试工作带来了便利。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值