Spring学习-4-手动实现AOP编程

AOP面向切面编程

AOP可以实现“业务代码”和“关注点代码”完全分离

  @Override
    public List<Message> findAllMessage() {

        Session session = null;  //关注点代码
        Transaction tx = null;

        try{

            session = HibernateUtils.getSession();

            tx = session.beginTransaction();  //关注点代码

            Query q = session.createQuery("from Message order by write_time desc "); //业务代码

            return q.list();  //业务代码

        }catch (Exception e){

            throw new RuntimeException(e);  //关注点代码
        }finally {

            tx.commit();
            session.close();  //关注点代码

        }

    }

  

分析:

关注点代码,就是指重复执行的代码。

业务代码和关注点代码分离,好处?

--关注点代码写一次即可

--开发者只需要关注核心业务

--运行期间,执行业务代码的时候动态的植入关注点代码;(代理实现)

如何分离

过程式/对象式/代理模式分离

手动实现aop编程实例一:

package aop;

import org.springframework.stereotype.Component;

/**
 * Created by cxspace on 16-8-10.
 */

@Component //加入ioc容器

public class Aop {
    //重复执行的代码
    public void begin(){
        System.out.println("开始事务");
    }

    public void commite(){
        System.out.println("提交事务");
    }

}

package aop;

/**
 * Created by cxspace on 16-8-10.
 */
public interface IUserDao {
    public void save();
}

package aop;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Created by cxspace on 16-8-10.
 */

@Component
public class UserDao implements IUserDao{

    @Resource
    private Aop aop;

    @Override
    public void save() {
        aop.begin();
        System.out.println("保存数据!");
        aop.commite();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启注解扫描-->
    <context:component-scan base-package="aop"></context:component-scan>

</beans>

package aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by cxspace on 16-8-10.
 */
public class App {

    ApplicationContext ac = new ClassPathXmlApplicationContext("aop/bean.xml");

    @Test
    public void test(){

        IUserDao userDao = (IUserDao)ac.getBean("userDao");
        userDao.save();

    }
}

手动实现AOP编程实例二(代理)

package aopProxy;

/**
 * Created by cxspace on 16-8-10.
 */
public interface IUserDao {
    public void save();
}

package aopProxy;

import org.springframework.stereotype.Component;

/**
 * Created by cxspace on 16-8-10.
 */

@Component
public class UserDao implements IUserDao {

    @Override
    public void save() {

        System.out.println("保存数据!");

    }
}

package aopProxy;

import org.springframework.stereotype.Component;

/**
 * Created by cxspace on 16-8-10.
 */

@Component //加入ioc容器

public class Aop {
    //重复执行的代码
    public void begin(){
        System.out.println("开始事务");
    }

    public void commite(){
        System.out.println("提交事务");
    }

}

package aopProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by cxspace on 16-8-10.
 */
public class ProxyFactory {

    //目标对象
    private static Object target;

    private static Aop aop;

    //生成代理对象方法
    public static Object getProxyInstance(Object target_,Aop aop_){

        target = target_;
        aop = aop_;

        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        aop.begin();

                        Object returnValue = method.invoke(target,args);

                        aop.commite();

                        return returnValue;
                    }
                }
        );

    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启注解扫描-->
    <context:component-scan base-package="aopProxy"></context:component-scan>

    <!--调用工厂方法,返回UserDao代理后的对象-->
    <bean id="userDao_proxy" class="aopProxy.ProxyFactory" factory-method="getProxyInstance">
        <constructor-arg index="0" ref="userDao"></constructor-arg>
        <constructor-arg index="1" ref="aop"></constructor-arg>
    </bean>

</beans>

package aopProxy;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by cxspace on 16-8-10.
 */
public class App {

    ApplicationContext ac = new ClassPathXmlApplicationContext("aopProxy/bean.xml");

    @Test
    public void test(){

        IUserDao userDao = (IUserDao)ac.getBean("userDao_proxy");

        System.out.println(userDao.getClass());

        userDao.save();

    }

}

  

时间: 2024-11-19 17:35:12

Spring学习-4-手动实现AOP编程的相关文章

Spring学习之第一个AOP程序

IOC和AOP是Spring的两大基石,AOP(面向方面编程),也可称为面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行 OOP 开发时,都是基于对组件(比如类)进行开发,然后对组件进行组合,OOP 最大问题就是无法解耦组件进行开发,比如我们上边举例,而 AOP 就是为了克服这个问题而出现的,它来进行这种耦合的分离.AOP 为开发者提供一种进行横切关注点(比如日志关注点)分离并织入的机制,把横切关注点分离,然后通过某种技术织入到系统中,从而无耦

Spring学习记录(十二)---AOP理解

Spring核心之二:AOP(Aspect Oriented Programming) --- 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. 专业术语: Joinpoint(连接点): 所谓连接点是指那些被拦截到的点.在spri

spring学习笔记四:AOP

AOP(Aspect Orient Programming),面向切面编程,是对面向对象编程OOPS的一种补充 面向对象编程使用静态角度考虑程序的结构,而面向切面编程是从动态角度考虑程序运行过程 AOP底层,就是采用动态代理模式实现的.采用了两种代理:JDK的动态代理域CGLIB的动态代理 AOP编程属于: 1.切面(Aspect) 切面泛指交叉业务逻辑 2.织入(weaving) 织入是指将切面代码插入到目标对象的过程 3.切入点(Pointcut) 切入点指切面具体织入的位置 4.目标对象(

Spring学习(十三)aop技术理解与使用

一.什么是AOP? aop技术是面向切面编程思想,作为OOP的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想.AOP底层也是面向对象:只不过面向的不是普通的Object对象,而是特殊的AOP对象.AOP的关注点是组成系统的非核心通用服务模块(比如登录检查等),相对于普通对象,aop不需要通过继承.方法调用的方式来提供功能,只需要在xml文件中以引用的方式,将非核心服务功能引用给需要改功能的核心业务逻辑对象或方法中.最终实现对象的解耦.spring 中ioc技术实现了核心

Spring学习笔记三(AOP中的那些事)

1.前言 前两篇博客介绍了一下,Spring中的IOC容器,这篇来讲解一下Spring中的AOP的知识.  2.AOP基础知识 2.1 概念 AOP是一种面向切面编程,一种软件工程的编程范式.AOP关注的是程序中的共性的功能,开发时,将共性功能抽取出来制作成独立的模块,此时原始代码中将不再具有这些被抽取出来的共性功能代码.因此加强了代码的复用性,同时程序开发时可以只考虑个性化功能,不需要考虑共性的功能. 2.2 基本知识点 连接点:具有特定功能的方法,一般方法 切入点:具有共性功能的方法的统称的

Spring学习笔记五: AOP入门

一.AOP术语 切面(aspect):要实现的交叉功能,是系统模块化的一个切面或领域.如日志记录. 连接点:应用程序执行过程中插入切面的地点,可以是方法调用,异常抛出,或者要修改的字段. 通知:切面的实际实现,他通知系统新的行为.如在日志通知包含了实 现日志功能的代码,如向日志文件写日志.通知在连接点插入到应用系统中. 切入点:定义了通知应该应用在哪些连接点,通知可以应用到AOP框架支持的任何连接点. 引入:为类添加新方法和属性. 目标对象:被通知的对象.既可以是你编写的类也可以是第三方类. 代

Spring学习1_面向切面( AOP )实现原理

面向切面编程 (Aspect Oriented Programming,简称AOP) 是Spring的一个重要特性,其原理是采用动态代理方式实现. 下面通过一个Demo来模拟AOP实现 整个代码目录结构如下: 其中LogInterceptor类完成为所有Service方法添加日志记录的功能. 1.Dao层实现 package com.dao; public class UserDaoImpl implements UserDao { @Override public void save() {

(5)手动实现AOP编程

1.面向对象.面向接口.面向切面编程 面向对象编程(OOP),是将现实的事物抽象为包含property和method的class,它是对面向过程编程的一种演变,能够实现代码的重用,它实现的是代码级别的抽象. 面向接口编程,它是以功能相近的方法组织到一个接口内,它实现的是功能级别的抽象. 面积切面编程,它实现业务功能和关注点的分离,它实现的是业务级别的抽象. Difference Between AOP and OOP http://www.differencebetween.com/differ

Spring学习(21)--- AOP之Advice应用(上)

前置通知(Before advice) 在某个连接点(join point)之前执行的通知,但不能阻止连接点前的执行(除非它抛出异常) 返回后通知(After returning advice) 在某个连接点(join point)正常完成后执行的通知 抛出异常后通知(After throwing advice) 在方法抛出异常退出时执行的通知 后通知(After(finally) advice) 当某个连接点退出的时候执行的通知(无论是正常返回还是异常退出) 环绕通知(Around advic