Spring框架之AOP概念详解和应用(二)

2022-07-14  本文已影响0人  程序猿峰岑
AOP概述
AOP实现原理
AOP术语

手动代理

JDK动态代理
 public static IUserService createUserService() {
        final MyAspect myAspect = new MyAspect();
        final IUserService userService = new UserServiceImpl();
        IUserService proxy = (IUserService)Proxy.newProxyInstance(MyFactory.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                myAspect.before();
                Object obj = method.invoke(userService,args);
                System.out.println("拦截返回值:" + obj);
                myAspect.after();
                return obj;
            }
        });

        return proxy;
    }
CGLib增强字节码
public static IUserService createUserService() {
   //目标类
   final IUserService userService = new UserServiceImpl();
   //切面类
   final MyAspect aspect = new MyAspect();
   //3 cglib核心类
   Enhancer enhancer = new Enhancer();
   enhancer.setSuperclass(userService.getClass());
   enhancer.setCallback(new MethodInterceptor() {
      @Override
      public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
             aspect.before();
             Object obj = methodProxy.invokeSuper(proxy,args);
             aspect.after();
             return obj;
         }
      });
  UserServiceImpl proxy = (UserServiceImpl) enhancer.create();
  return proxy;
}
AOP联盟通知类型

AOP联盟通知Advice定义了org.aopalliance.Advice.
Spring按照通知Advice在目标类方法的连接点位置,可以分为5类。

Spring 编写代理半自动

目标掌握让Spring创建代理对象,从Spring容器中手动的获取代理对象。
第一步:导入jar包
核心4+1,AOP联盟(规范)、Spring-aop(实现)
com.springsource.org-aopalliance-1.0.0.jar AOP联盟
spring-aop-3.2.0.RELEASE.jar AOP实现。
第二步:目标类
IUserService

public interface IUserService {
    void addUser(User user);
    void updateUser(User user);
    void delete(String username);
}

UserServiceImpl

@Service("userService")
public class UserServiceImpl implements IUserService {
    
    private UserDaoImpl userDao = new UserDaoImpl();

    public void setUserDao(UserDaoImpl userDao) {
        this.userDao = userDao;
    }

    @Override
    public void addUser(User user) {
        userDao.save(user);
    }

    @Override
    public void updateUser(User user) {
        userDao.update(user);
    }

    @Override
    public void delete(String username) {
        userDao.delete(username);
    }
}

第三步:切面类

public class UserAspect implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("before...................");
        Object obj = methodInvocation.proceed();
        System.out.println("after....................");
        return obj;
    }
}

第四步:Spring配置

<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context ="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="myAspect" class="com.zzx.aspect.UserAspect"></bean>
    <bean id="userDao" class="com.zzx.dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="com.zzx.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>
    <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="interfaces" value="com.zzx.service.IUserService"/>
        <property name="target" ref="userService"/>
        <property name="interceptorNames" value="myAspect"/>
        <!--配置使用cglib-->
        <property name="optimize" value="true"></property>
    </bean>
</beans>
Spring AOP全自动编程

第一步:导入jar包 aspectjweaver-1.8.13.jar下载及Maven、Gradle引入代码,pom文件及包内class -时代Java (nowjava.com)
第二步:Spring的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:context ="http://www.springframework.org/schema/context"
                xmlns:aop ="http://www.springframework.org/schema/aop"
                xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.zzx.service.impl.UserServiceImpl"/>
<bean id="myAspect" class="com.zzx.aspect.UserAspect"/>

<aop:config proxy-target-class="true">
    <aop:pointcut id="pointcut" expression="execution(* com.zzx.service.*.*(..))"/>
    <aop:advisor advice-ref="myAspect" pointcut-ref="pointcut"/>
</aop:config>

</beans>

切入点 expression表达式 execution(* 报名..(..)) 第一个“”固定写法,第二个“”表示的是任意类名,第三个“*”表示的是任意方法名称,"(..)"表示的是任意参数。

上一篇 下一篇

猜你喜欢

热点阅读