掌握Spring5.X注解配置、基于注解配置AOP面向切面编程

常用注解

扫描指定的包,包括子包:context.scan("net.xdclass.sp");
里面完成初始化操作,核心方法:context.refresh();

bean定义
@Component通用组件
细分:@Controller (⽤于web层) @Service (用于service层) @Repository (用于dao仓库层)

bean取名
@Component("XXXX")

bean注⼊
类型注⼊@Autowired名称注⼊@Qualifier

bean生命周期
@PostConstruct初始化、@PreDestroy销毁

bean作用范围
@scope注解

注释举例:

package net.xdclass.sp.service;
import net.xdclass.sp.domain.Video;
import org.springframework.stereotype.Component;

//@Component("自定义名称")
@Component
public class VideoServiceImpl implements VideoService {
    public int save(Video video) {
        System.out.println("保存video");
        return 1;
    }
    public Video findById(int id) {
        System.out.println("根据id找视频");
        return new Video();
    }
}

主类运行,测试:

package net.xdclass.sp;

import net.xdclass.sp.domain.Video;
import net.xdclass.sp.service.VideoService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        //扫描指定的包,包括子包
        context.scan("net.xdclass.sp");
        //里面完成初始化操作,核心方法
        context.refresh();

        VideoService videoService = (VideoService) context.getBean("videoServiceImpl");
        videoService.findById(2);
        Video video = (Video) context.getBean("video");
        video.init();
    }
}

定义第三方bean
@Configuration标注在类上,相当于把该类作为spring的xml配置⽂件中的<bean>
作⽤:配置spring容器(应用上下文)
@bean注解:用于告诉⽅法产⽣⼀个Bean对象,然后这个Bean对象交给Spring管理,Spring将会将这个Bean对象放在自己的IOC容器中

注意点:SpringIOC容器管理⼀个或者多个bean,这些bean都需要在@Configuration注解下进行创建

package net.xdclass.sp.config;
import net.xdclass.sp.domain.VideoOrder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class AppConfig {
    // 使用@bean注解,表明这个bean交个spring 进行管理
    // 如果没有指定名称,默认采用 方法名 + 第一个字母小写 作为bean的名称
    @Bean(name = "videoOrderName",initMethod = "init",destroyMethod = "destroy")
    @Scope
    public VideoOrder videoOrder(){
        return new VideoOrder();
    }
}

@PropertySource,指定加载配置文件(config.properties),配置文件映射到实体类,使用@Value映射到具体的java属性

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = {"classpath:config.properties"})
public class CustomConfig {
    @Value("${server.host}")
    private String host;
    @Value("${server.port}")
    private int port;
    
    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
}

在这里插入图片描述

基于注解配置AOP面向切面编程

声明切面类

@Aspect(切面):通常是⼀个类,⾥⾯可以定义切入点和通知

配置切入点和通知

@Component
//告诉spring,这个一个切面类,里面可以定义切入点和通知
@Aspect
public class LogAdvice {
    //切入点表达式
    @Pointcut("execution(* net.xdclass.sp.service.VideoServiceImpl.*(..))")
    public void aspect(){}

    //前置通知
    @Before("aspect()")
    public void beforeLog(JoinPoint joinPoint){
        System.out.println("LogAdvice  beforeLog");
    }
    //后置通知
    @After("aspect()")
    public void afterLog(JoinPoint joinPoint){
        System.out.println("LogAdvice  afterLog");
    }
}

开启SpringAOP注解配置

@Configuration
@ComponentScan("net.xdclass")
@EnableAspectJAutoProxy  //开启了spring对aspect的支持
public class AnnotationAppConfig {
}

效果测试

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationAppConfig.class);
        VideoService videoService = (VideoService) context.getBean("videoService");
        videoService.findById(2);
    }
}

在这里插入图片描述

环绕通知统计接口耗时

在切面类中配置环绕通知:打印⽅法请求耗时时间
环绕通知获取⽬标方法和参数

	//环绕通知
    @Around("aspect()")
    public void around(JoinPoint joinPoint){

        Object target = joinPoint.getTarget().getClass().getName();
        System.out.println("调用者="+target);

        //目标方法签名
        System.out.println("调用方法="+joinPoint.getSignature());

        //通过joinPoint获取参数
        Object [] args = joinPoint.getArgs();
        System.out.println("参数="+args[0]);

        long start = System.currentTimeMillis();
        System.out.println("环绕通知 环绕前=========");
        //执行连接点的方法
        try {
            ((ProceedingJoinPoint)joinPoint).proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("环绕通知 环绕后=========");

        System.out.println("调用方法总耗时 time = " + (end - start) +" ms");
    }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

豆浆两块钱

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值