spring学习路线:day04--面向切面编程(aop详解)

一:Aop简介

  1. aop:aspect oriented programming 面向切面编程

  2. aop在spring中作用

    提供声明式服务(声明式事务)
    允许用户实现自定义切面
    spring aop就是将公共的业务(如日志,安全等)和领域业务结合。当执行领域业务时将会把公共业务加进来。实现公共业务的重复利用。领域业务更纯粹。程序猿专注于领域业务。其本质还是动态代理。

  3. aop编程与传统编程模式比较
    传统编程模式:
    在这里插入图片描述
    aop编程模式:横向的编程,在不改变原来的代码下增加新的功能
    在这里插入图片描述

  4. aop的好处:

    • 使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情。
    • 公共的业务由代理来完成–实现业务的分工
    • 公共业务发生扩展时变得更加集中和方便
      5.名词解释
      关注点:增加的某个业务。如日志,安全,缓存,事务等。
      切面(Aspect):一个关注点的模块化。例如把一个方法封装成一个类。
      通知(Advice):在切面的某个特定的连接点(方法)上执行的动作。
      织入(Weaving):把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象。
  5. aop就是把一类的功能封装起来,通过切面的方式加入到其它业务中

二:使用spring实现aop

1.通过springAPI实现

Log–前置通知:

public class Log implements MethodBeforeAdvice{
    /**前置通知:目标方法执行前执行的通知
     * method 被调用的方法对象
     * args 被调用的方法的参数
     * target 被调用方法的目标对象
     */
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(arg2.getClass().getName()+"的"+arg0.getName()+"方法被调用");
		
	}
   
}

AfterLog–后置通知

public class Log implements MethodBeforeAdvice{
    /**前置通知:目标方法执行前执行的通知
     * method 被调用的方法对象
     * args 被调用的方法的参数
     * target 被调用方法的目标对象
     */
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(arg2.getClass().getName()+"的"+arg0.getName()+"方法被调用");
		
	}
   
}

实现类UserServiceImpl:

public class UserServiceImpl implements UserService{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("增加用户");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("更新用户");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("删除用户");
	}

	@Override
	public void search() {
		// TODO Auto-generated method stub
		System.out.println("查找用户");
	}

}

配置文件beans:

<?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:c="http://www.springframework.org/schema/c"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="userService" class="net.xyz.service.UserServiceImpl"></bean>
    <bean id="log" class="net.xyz.log.Log"></bean>
    <bean id="afterLog" class="net.xyz.log.AfterLog"></bean>
    <aop:config>
       <!-- 配置指定类下的所有方法,并能涵盖所有参数 -->
        <aop:pointcut expression="execution(* net.xyz.service.UserServiceImpl.*(..))" id="pointcut"/>
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
</beans>

测试类:

public class Text {
	public static void main(String[] args) {
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
		UserService userService =(UserService) ac.getBean("userService");
		userService.add();
		userService.delete();
	}

}

2.自定义类实现aop

log.java

public class Log {
  public void before() {
	  System.out.println("----在方法之前执行--------");
  }
  public void after() {
	  System.out.println("----在方法之后执行-------");
  }
}

UserServiceImpl:

public class UserServiceImpl implements UserService{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("增加用户");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("更新用户");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("删除用户");
	}

	@Override
	public void search() {
		// TODO Auto-generated method stub
		System.out.println("查找用户");
	}

}

配置文件:

public class UserServiceImpl implements UserService{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("增加用户");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("更新用户");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("删除用户");
	}

	@Override
	public void search() {
		// TODO Auto-generated method stub
		System.out.println("查找用户");
	}

}

控制台显示:
在这里插入图片描述

3.通过注解方式实现aop

配置文件:

<?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:c="http://www.springframework.org/schema/c"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="userService" class="net.xyz.service.UserServiceImpl"></bean>
    <bean id="log" class="net.xyz.log.Log"></bean>
     <aop:aspectj-autoproxy>
     </aop:aspectj-autoproxy>
</beans>

log.java

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.MethodBeforeAdvice;
@Aspect
public class Log {
  @Before("execution(* net.xyz.service.UserServiceImpl.*(..))")//方法前执行
  public void before() {
	  System.out.println("----在方法之前执行--------");
  }
  @After("execution(* net.xyz.service.UserServiceImpl.*(..))")//方法后执行
  public void after() {
	  System.out.println("----在方法之后执行-------");
  }
  @Around("execution(* net.xyz.service.UserServiceImpl.*(..))")//环绕通知,方法前后都会执行
  public Object around(ProceedingJoinPoint jp) throws Throwable {
	  System.out.println("环绕前");
	  System.out.println("签名:"+jp.getSignature());
	  //执行目标方法
	  Object result =jp.proceed();
	  System.out.println("环绕后");
	  return result;
  }
}

Text类:

public class Text {
	public static void main(String[] args) {
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
		UserService userService =(UserService) ac.getBean("userService");
		userService.add();
	}

}

控制台:
在这里插入图片描述
最后:文章中出现的任何资源都可以私聊我要哟,就不要上传资源了,很麻烦。

猜你喜欢

转载自blog.csdn.net/qq_44867340/article/details/106289782
今日推荐