首页 专题 文章 代码 归档
spring半自动创建代理
2020.01.26 18:34 2020.01.26 18:34

1. spring编写代理:半自动

让spring创建代理对象,从spring容器中手动的获取代理对象。

1.1. 导入jar包

核心jar包:4+1

  • spring-core
  • spring-beans
  • spring-context
  • spring-expression
  • commons-logging

AOPjar包:AOP联盟(规范)、Spring-aop(实现)

2. 执行代码

2.1. 目标类

package com.misiai.c_spring_01.a_jdk;

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("Add User");
    }

    @Override
    public void updateUser() {
        System.out.println("Update User");
    }

    @Override
    public void deleteUser() {
        System.out.println("Delete User");
    }
}

2.2. 切面类

package com.misiai.c_spring_01.a_jdk;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。
 * 采用环绕通知 MethodInterceptor
 */
public class MyAspect implements MethodInterceptor {


     //采用环绕通知
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        // 前置
        System.out.println("前置333");
        // 手动执行方法
        Object object = methodInvocation.proceed();
        // 后置
        System.out.println("后置333");
        return object;
    }
}

2.3. 配置文件

<?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:aop="http://www.springframework.org/schema/aop"
       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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    <!--目标类-->
    <bean id="userService" class="com.misiai.c_spring_01.UserServiceImpl"/>
    <!--切面类-->
    <bean id="myAspect" class="com.misiai.c_spring_01.MyAspect"/>
    <!--    代理类
        史用工厂bean FactoryBean,底层调用getObject()返回特殊bean
        ProxyFactoryBean用于创建代理工厂bean,生成特殊代理对象

        interfaces:确定接口i通过<array>可以设置多个值只有一个值时,value=""
        target:确定目标类
        interceptorNames:通知切面类的名称,类型String[]
    -->
    <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="interfaces" value="com.misiai.c_spring_01.UserService"/>
        <property name="target" ref="userService"/>
        <property name="interceptorNames" value="myAspect"/>
    </bean>


</beans>

2.4. 测试类

package com.misiai.c_spring_01;

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

public class SpringTest {

    @Test
    public void test01() {
        ApplicationContext ap = new ClassPathXmlApplicationContext("applicationContext.xml");

        /*获得代理类id*/
        UserService userService = (UserService) ap.getBean("proxyFactoryBean");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }
}

结果:

截图-1580013827

3. spring底层

3.1. 底层机制

自动判断:

  • 接口+实现类:使用jdk动态代理
  • 实现类:使用cglib

强制使用:

<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="interfaces" value="com.misiai.c_spring_01.UserService"/>
    <property name="target" ref="userService"/>
    <property name="interceptorNames" value="myAspect"/>
    <property name="optimize" value="true"/>
</bean>

加上一个optimize=true,即可强制使用cglib为底层代理。

截图-1580016566

本节阅读完毕! (分享
二维码图片 扫描关注我们哟