首页 > 编程语言 > 详细

spring 动态代理开发的切入点表达式

时间:2021-05-31 11:57:41      阅读:10      评论:0      收藏:0      [点我收藏+]

spring 动态代理开发的切入点表达式

在前面总结了spring的动态代理开发的步骤,指定增强类(额外功能)的使用,那有了功能,还需要指定使用功能的地方,就需要切入表达式来指定切入的地点

1,演示文件结构和类实现

先看下文件目录和类实现,可以更好的演示切入点表达式所达到的效果

技术分享图片

cutexpress包

UserPoxyBefore

用于指定增强的方法,如果实现了代理则可以看到打印出的增强类方法名

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class UserPoxyBefore implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("UserPoxyBefore.before");
    }
}

userservice2接口

用于实现UserServiceImpl_type

public interface UserService2 {
     void login(String id);
}

UserServiceImpl_type

用于测试同方法名不同参数个数

public class UserServiceImpl_type implements UserService2 {
    @Override
    public void login(String id) {
        System.out.println("org.Service.Cutexpress.UserServiceImpl_type.login"+id);
    }
}

cutexpress.UserServiceImpl

用于测试不同包的同类名,同方法名

public class UserServiceImpl implements UserService {

    @Override
    public void register(User user) {
        System.out.println("org.Service.Cutexpress.UserServiceImpl.register");
    }

    @Override
    public Boolean login(String name, String password) {
        System.out.println("org.Service.Cutexpress.UserServiceImpl.login "+name+" "+password );
        return true;
    }
}

UserServiceImpl_FB

用于测试同包不同类名

public class UserServiceImpl_FB implements UserService {

    @Override
    public void register(User user) {
        System.out.println("org.Service.Cutexpress.UserServiceImpl_FB.register");
    }
    @log
    @Override
    public Boolean login(String name, String password) {
        System.out.println("org.Service.Cutexpress.UserServiceImpl_FB.login "+name+" "+password );
        return true;
    }
}

service 包

实现各种UserService接口的类

public interface UserService {
    public void register(User user);

    public void login(String name, String password);
}

UserServiceImpl

用于测试不同包同方法名

public class UserServiceImpl implements UserService {

    @Override
    public void register(User user) {
        System.out.println("rg.Service.UserServiceImpl.register");

    }

    @Override
    public Boolean login(String name, String password) {
        System.out.println("rg.Service.UserServiceImpl.login "+name+" "+password );
        return true;
    }
}

配置文件

把各个类的bean写进去

expression暂时为空,等下填表达式测试

用的增强类UserPoxyBefore

<bean id="UserServicePiont" class="org.Service.Cutexpress.UserServiceImpl"/>
<bean id="UserServicePiont2" class="org.Service.UserServiceImpl"/>

<bean id="UserPoxyBefore" class="org.Service.Cutexpress.UserPoxyBefore"  />

<bean id="FB" class="org.Service.Cutexpress.UserServiceImpl_FB"/>
<bean id="type" class="org.Service.Cutexpress.UserServiceImpl_type"/>

<aop:config  >
    <aop:pointcut id="UserPoxyPC"  expression=""/>
    <aop:advisor advice-ref="UserPoxyBefore" pointcut-ref="UserPoxyPC"/>
</aop:config>

测试类

@Test
    public void test2() {
        ApplicationContext context=new ClassPathXmlApplicationContext("/ApplicationContext2.XML");
        //org.Service.UserServiceImpl 对比包
        UserService userService_= (UserService) context.getBean("UserServicePiont2");
        userService_.login("SY", "123456");
        userService_.register(new User());
        //org.Service.Cutexpress.UserServiceImpl 同类不同包
        UserService userService= (UserService) context.getBean("UserServicePiont");
        userService.login("SY", "123456");
        userService.register(new User());
        //org.Service.Cutexpress.UserServiceImpl_FB 同包不同类
        UserService userService2=(UserService) context.getBean("FB");
        userService2.login("SY", "123456");
        //org.Service.Cutexpress.UserServiceImpl_type 实现的方法只有一个
        UserService2 userService3=(UserService2) context.getBean("type");
        userService3.login("32");
    }

2.切入点表达式

1.expression函数(方法->类->包)

对于方法:

? 对所有方法都代理:*** (..)*

? 执行结果:所有方法均被代理

? 技术分享图片

? 对于所有login方法: *** login(..)**

? 技术分享图片

? 指定参数 数量,类型

? 对于只有一个String参数的:login(String)

? 技术分享图片

?

? 对于有二个String参数的 :*** login(String,String)**

? 技术分享图片

?

? 参数和..连用:*** login(String,..)**

? 表示第一个参数是String的所有方法

? 技术分享图片

?

? 指定非Java.lang包中的对象:*** register(org.User)**

? 技术分享图片

?

? 精确切入某个方法(权限名命)特别注意星号

? *** org.Service.Cutexpress.UserServiceImpl_FB.login(..)**

? 技术分享图片

对于类:

? 指定某个类的所有方法

? *** org.Service.Cutexpress.UserServiceImpl.*(..)**

? 技术分享图片

?

? 对于多级包(搜索所有包中符合方法名字的类)

? *** ..UserServiceImpl.(..)**

? 技术分享图片

对于包:

? 对于某个包的所有类的方法

? *** org.Service..(..)**

? 技术分享图片

?

? 对于某个包的子包

?
$$

  • org.Service...(..)
    $$
    ? 技术分享图片

?

2.其他函数、

args

? args主要用于参数的匹配,填写参数就可以,注意在expression中的expression替换为args 例如:

<aop:pointcut id="UserPoxyPC"  expression=" args(String)  "/>

? args(String),匹配一个String参数的方法

? 技术分享图片

within

? within 用于对包,类的匹配(*代表类或者包)

? within(*..UserServiceImpl) 匹配所有的UserServiceImpl类

? 技术分享图片

?

? within(org.Service.Cutexpress..*) 匹配所有的org.Service.Cutexpress包下的类

? 技术分享图片

3.对于注解

? 自定义一个注解

package org;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface log {
}

在想实现代理的类上注解,如UserServiceImpl_FB

? 技术分享图片

4.对于不同函数的运算

配置文件如:

 <aop:pointcut id="UserPoxyPC"  expression="execution(* login(..)) and args(String)"/>

and

比如 所有的login方法 同时满足 一个String参数都代理

execution(* login(..)) and args(String)

? 技术分享图片

or

比如所有的login方法 和 一个String参数的方法都代理

login(..) or args(String)

? 技术分享图片

3.总结

对于一个方法的实现我们要有以下要素:

权限 返回值 方法名(参数)

抽象为

权限 返回值 方法名 (参数)
* * (..)

不难发现*** (..)* 就是所有的方法的表达方式

无论需求是方法 类 还是包

第一个*就代表权限 第二个是路径 第三个是方法,以此类推。

同时一个表达式可以由多个表达式实现,不要拘泥于某个表达方式

spring 动态代理开发的切入点表达式

原文:https://www.cnblogs.com/ShanYu-Home/p/14829763.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!