Java——面向切面编程,Spring中的AOP编程

面向切面编程

AOP思想:将横向重复代码,纵向抽取出来

AOP体现——Filter

AOP体现——拦截器

AOP体现——动态代理

Spring中实现AOP思想

原理:Spring可以为容器中管理的对象生成代理对象

代理分为动态代理和cglib代理:

  • 动态代理(优先)
    • 被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术,换句话说,就是代理对象和被代理要实现同一接口
  • cglib代理
    • 第三方代理技术,cglib代理,可以对任何类生成代理,代理的原理是对目标对象进行继承代理,如果目标对象被final修饰,那么该类无法被cglib代理
    • Hibernate的实体使用的是cglib代理

名次解释

代码实现:

1) 导包

4+2

spring-aop-4.2.4.RELEASE.jar

spring-aspects-4.2.4.RELEASE.jar

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

2)准备接口和实现类

UserService接口

public interface UserService {
	void save();
	void delete();
	void update();
	void find();
}

UserServiceImpl实现类

public class UserServiceImpl implements UserService {
	@Override
	public void save() {
		System.out.println("保存用户!");
		//int i = 1/0;
	}
	@Override
	public void delete() {
		System.out.println("删除用户!");
	}
	@Override
	public void update() {
		System.out.println("更新用户!");
	}
	@Override
	public void find() {
		System.out.println("查找用户!");
	}
}

3)准备通知(要往里面织入的代码)

//通知类
public class MyAdvice {

	//前置通知
	public void before(){
		System.out.println("这是前置通知!!");
	}
	
	//后置通知
	public void afterReturning(){
		System.out.println("这是后置通知(如果出现异常不会调用)!!");
	}
	
	//环绕通知
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("这是环绕通知之前的部分!!");
		Object proceed = pjp.proceed();//调用目标方法
		System.out.println("这是环绕通知之后的部分!!");
		return proceed;
	}
	
	//异常通知
	public void afterException(){
		System.out.println("出事啦!出现异常了!!");
	}
	
	//后置通知
	public void after(){
		System.out.println("这是后置通知(出现异常也会调用)!!");
	}
}

4)配置进行织入,将通知织入目标对象中

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

    <!--1.配置目标对象-->
    <bean name="userService" class="cn.x5456.service.impl.UserServiceImpl"></bean>
    <!--2.配置通知对象-->
    <bean name="myAdvice" class="cn.x5456.advice.MyAdvice"></bean>
    <!--3.配置织入点-->
    <aop:config>
        <!--id任意,配置切点-->
        <aop:pointcut id="pc" expression="execution(* cn.x5456.service.impl.*ServiceImpl.*(..))"></aop:pointcut>
        <!--配置通知,ref是通知的类名-->
        <aop:aspect ref="myAdvice">
            <!--method与通知对象中的方法名对应,pointcut为织入点的id-->
            <!-- 指定名为before方法作为前置通知 -->
            <aop:before method="before" pointcut-ref="pc" />
            <!-- 后置 -->
            <aop:after-returning method="afterReturning" pointcut-ref="pc" />
            <!-- 环绕通知 -->
            <aop:around method="around" pointcut-ref="pc" />
            <!-- 异常拦截通知 -->
            <aop:after-throwing method="afterException" pointcut-ref="pc"/>
            <!-- 后置 -->
            <aop:after method="after" pointcut-ref="pc"/>
        </aop:aspect>

    </aop:config>

</beans>

5)测试类

public class testDemo {

    @Test
    public void func(){

        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");

        UserService userService = (UserService) ac.getBean("userService");

        userService.save();

    }

}
原文地址:https://www.cnblogs.com/x54256/p/8485778.html