Day11 AOP介绍

1 前言

AOP,Aspect Oriented Programming,面向切面编程,是对面向对象编程OOP的升华。OOP是纵向对一个事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是横向的对不同事物的抽象属性与属性、方法与方法、对象与对象都可以组成一个切面,而用这种思维去设计编程的方式叫做面向切面编程。

将两个对象的若干方法临时组装在一起,使用更加灵活。resist 是主方法,getException为增强方法。

1.1 AOP思想的实现方案

动态代理技术,在运行期间对目标对象的方法进行增强,代理对象同名方法内可以执行原有逻辑的同时嵌入执行其他增强逻辑或其他对象的方法。

2 简单模拟AOP实现

【第一步】目标bean(等待被增强)

package org.example.service.impl;

import org.example.service.UserService;

/**
 * @author : msf
 * @date : 2023/1/26
 */
public class UserServiceImpl implements UserService {
    @Override
    public void show1() {
        System.out.println("show1....");
    }

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

【第二步】增强的类

// 增强类,内部提供增强方法
public class MyAdvice {
    public void beforeAdvice(){
        System.out.println("前置增强...");
    }

    public void afterAdvice(){
        System.out.println("后置增强...");
    }
}

【第三步】配置处理器

  1. 实现beanpostpropocessor和applicationaware

难点

1. 筛选service.impl包下的所有类都会增强? -->通过反射获取

2. MyAdvice 怎么获取? -->从spring容器中获取。

package org.example.processor;

import org.example.advice.MyAdvice;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

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

/**
 * @author : msf
 * @date : 2023/1/26
 */
public class AopBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        // 对userServiceImpl 的两个方法进行增强

        // 问题1. 筛选service.impl包下的所有类都会增强? -->通过反射获取
        // 问题2. MyAdvice 怎么获取? -->从spring容器中获取。
        if ("org.example.service.impl".equals(bean.getClass().getPackage().getName())) {
            // 生成当前bean的proxy对象
            Object beanProxy = Proxy.newProxyInstance(
                    bean.getClass().getClassLoader(),
                    bean.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            // 获取增强对象的增强方法
                            MyAdvice myAdvice = applicationContext.getBean("myAdvice", MyAdvice.class);
                            myAdvice.beforeAdvice();
                            Object result = method.invoke(bean, args);
                            myAdvice.afterAdvice();
                            return result;
                        }
                    }
            );
            return beanProxy;
        }
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

【第四步】通过xml进行IoC

<?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"
       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
       ">


    <!--配置目标对象-->
    <bean id="userService" class="org.example.service.impl.UserServiceImpl"/>
    <!--配置增强对象-->
    <bean id="myAdvice" class="org.example.advice.MyAdvice"/>
    <!--增强逻辑-->
    <bean class="org.example.processor.AopBeanPostProcessor"/>

    <!----><context:property-placeholder location="classpath:jdbc.properties"/>


    <!--注解组件扫描:扫描指定的基本包及其子包下的类,识别使用@Component注解-->
<!--    <context:component-scan base-package="org.example"/>-->


</beans>

【第五步】测试

public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.show1();
        //System.out.println("userService = " + userService);
    }
}

结果

总结如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兜兜转转m

一毛钱助力博主实现愿望

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值