Spring复习(下)

本文详细介绍了Spring框架中的表达式语言、字符串和数学计算操作,展示了如何在XML中使用Spring表达式进行属性注入,以及AOP切面编程的概念、execution表达式的使用和不同切面实现方法,包括接口切面和注解切面的应用。
摘要由CSDN通过智能技术生成

全文来自于https://itbaima.net/document

spring spel(了解)

  1. 很强的一个表达式 有空可以看看,可以搭配外部属性注入
    源于spring框架
  2. 文档地址
    https://docs.spring.io/spring-framework/reference/core/expressions/language-ref/literal.html
  3. 使用方法
  • 操作字符串
Expression exp = parser.parseExpression("'Hello World'.toUpperCase()");   //调用String的toUpperCase方法
System.out.println(exp.getValue()); //操作字符串
  • 数学计算
Expression exp2 = parser.parseExpression("99 + 99 * 3");   //算数运算
System.out.println(exp2.getValue());//数学计算

-xml中使用

<bean id="numberGuess" class="org.spring.samples.NumberGuess">
    <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
</bean>

外部属性注入

使用方式

  1. properties文件
  • 配置要注入的值
    resources/application.properties
test.name=hello
test.age=12
  1. @Component类
  • 这个类注入值 properties的值
@Component
public class Student {
    @Value("${test.name}")   //这里需要在外层套上 ${ }
    private String name;   //String会被自动赋值为配置文件中对应属性的值
    //构造方法中的参数除了被自动注入外,我们也可以选择使用@Value进行注入
    public Student(@Value("${test.name}") String name){
        this.name = name;
    }
}
  1. @Configuration类
  • 这个类扫描bean 且要扫描properties文件
@Configuration
@ComponentScan("com.test.bean")
@PropertySource("classpath:test.properties")   //注意,类路径下的文件名称需要在前面加上classpath:
public class MainConfiguration{
    
}

AOP 切面编程

概念

  • 有很多种AOP,不仅仅是前切,后切,环绕切
  • 切面表达式
    • 主要看execution表达式看懂即可,到时候拿chatgpt写去
    • 直接看这个https://blog.csdn.net/weixin_43793874/article/details/124753521?spm=1001.2014.3001.5506
  • 主要学习的execution填写格式如下:
修饰符 包名.类名.方法名称(方法参数)
  • 修饰符:public、protected、private、包括返回值类型、static等等(使用*代表任意修饰符)
  • 包名:如com.test(* 代表全部,比如com.*代表com包下的全部包)
  • 类名:使用*也可以代表包下的所有类
  • 方法名称:可以使用*代表全部方法
  • 方法参数:填写对应的参数即可,比如(String, String),也可以使用*来代表任意一个参数,使用…代表所有参数。
<aop:pointcut id="test" expression="execution(* org.example.entity.Student.study())"/>

1. xml进行切面

  • xml文件解释
    • <bean class="org.example.bean5.Student"/>:被切的类
    • <bean id="studentAOP" class="org.example.bean5.StudentAOP"/>:切的类
    • <aop:pointcut id="test" expression="execution(* org.example.bean5.Student.study())"/> 被切的方法,用切面表达式定位
    • <aop:aspect ref="studentAOP"> ref指向切的类
    • <aop:after method="afterStudy" pointcut-ref="test"/>
      • after 是在方法执行后切
      • afterStudy是AOP切面类中的方法
      • pointcut-ref指向被切的方法的id
  • xml格式
  <bean class="org.example.bean5.Student"/>
    <bean id="studentAOP" class="org.example.bean5.StudentAOP"/>
    <aop:config>
        <aop:pointcut id="test" expression="execution(* org.example.bean5.Student.study())"/>
        <aop:pointcut id="test2" expression="execution(* org.example.bean5.Student.study2(String))"/>
        <aop:pointcut id="test3" expression="execution(* org.example.bean5.Student.study3(String))"/>


        <aop:aspect ref="studentAOP">
            <aop:after method="afterStudy" pointcut-ref="test"/>
        </aop:aspect>
        <aop:aspect ref="studentAOP">
            <aop:after method="afterStudy2" pointcut-ref="test2"/>
        </aop:aspect>

        <aop:aspect ref="studentAOP">
            <aop:around method="around" pointcut-ref="test3"/>
        </aop:aspect>
    </aop:config>
  • 切面类解释
    • JointPoint:连接点,就是被切的方法 可以拿到很多需要的信息 比如参数
      • 前切,后切都用这个
    • ProceedingJoinPoint:效果和JointPoint一样,但是这个可以控制返回值
      • 环绕切用这个
public class StudentAOP {
  	//这个方法就是我们打算对其进行的增强操作
    public void afterStudy() {
        System.out.println("为什么毕业了他们都继承家产,我还倒给他们打工,我努力的意义在哪里...");
    }
//    这个JointPoint来自于AspectJ,
    public void afterStudy2(JoinPoint point){
        //这个str参数我们该从哪里拿呢?
        System.out.println("拿到的参数是:"+point.getArgs()[0]);
    }
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("添加的方法");
//        这里的返回值类型虽然是Object,但是实际上你需要人为控制的 你要知道切入的是什么返回值
        Object value = joinPoint.proceed(new Object[]{"Rust"});
        System.out.println("添加的方法");
        return value;
    }
}
  • 被切类
public class Student {
    public void study(){
        System.out.println("室友还在打游戏,我狠狠的学Java,太爽了"); 
      	//现在我们希望在这个方法执行完之后,打印一些其他的内容,在不修改原有代码的情况下,该怎么做呢?
    }
    public void study2(String str){  //现在方法有一个String类型的参数
        System.out.println(str);
    }
    public String study3(String str){
       
        return str;
    }
}

2. 接口进行切面

  • 接口切面解释
    • 通过接口进行切面,通过实现不同的接口,且不同的位置
    • 通过xml文件 进行切类和被切类的关联
  • 接口切面格式
public class StudentAOP implements MethodBeforeAdvice, AfterReturningAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("通过Advice实现AOP");
    }

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("我是方法执行之后的结果,方法返回值为:"+returnValue);
    }
}
  • 接口切面xml
  • 通过<aop:advisor advice-ref="studentAOP" pointcut-ref="test"/>进行切类被切的方法关联
  • <aop:pointcut id="test" expression="execution(* org.example.bean6.Student.study())"/>:被切的方法
  • 切面方法不用配置了,因为我们已经实现了接口,所以spring会自动识别
   <bean id="student" class="org.example.bean6.Student"/>
    <bean id="studentAOP" class="org.example.bean6.StudentAOP"/>
    <aop:config>
        <aop:pointcut id="test" expression="execution(* org.example.bean6.Student.study())"/>
<!--  这里只需要添加我们刚刚写好的advisor就可以了,注意是Bean的名字  -->
        <aop:advisor advice-ref="studentAOP" pointcut-ref="test"/>
    </aop:config>
  • 被切类
public class Student {
    public String study(){
        System.out.println("我是学习方法!");
        return "lbwnb";
    }
}

3. 注解进行切面

  • 注解切面解释
    • 通过注解进行切面,通过给切类注解@Aspect,对不同的位置用不同的注解@After@Before@Around
    • 给配置类添加@EnableAspectJAutoProxy注解
    • 给切类添加@Component注解
  • 配置类
@EnableAspectJAutoProxy
@ComponentScan("org.example.bean7")
@Configuration
public class MyC {

}
  • 切类
@Aspect
@Component
public class StudentAOP {
    @Before("execution(* org.example.bean7.Student.study())")  //execution写法跟之前一样
    public void before(){
        System.out.println("我是之前执行的内容!");
    }
    @Around("execution(* com.test.bean.Student.test(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("方法执行之前!");
        Object val = point.proceed();
        System.out.println("方法执行之后!");
        return val;
    }
}
  • 被切类
@Component
public class Student {
    public void study(){
        System.out.println("我是学习方法!");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值