Spring的Context、IOC、DI、AOP

一、Spring的Context

1、基本概念

context

程序运行所需的整个环境。

Application Context

应用程序的上下文,用于整个应用程序的Bean实例化、配置和生命周期。

2、常用类型

读取XML的上下文:ClassPathXmlApplicationContext( )

读取注解的上下文:AnnotationConfigApplicationContext( )

二、控制反转(IOC)

1、基本概念

IOC(Inversion of Control)是一种设计思想,依赖注入(DI)是实现控制反转的一种方式。

面向对象编程,对象的创建、依赖有对象自己管理,具有较强的耦合性。通过将依赖关系交给第三方统一控制、装配、管理,从而实现解耦。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三、依赖注入(DI)

1、基本概念

依赖注入是一种解耦组件之间依赖关系的一种设计模式。将对象的依赖关系由对自己创建变为由外部容器创建和注入的过程。

2、注入形式

  • setter方法注入
  • 构造函数注入
  • 接口注入
  • 字段(Field)注入

setter方法注入

采用自动装配的方式

// CD
public interface CompactDisc {
    void play();
}

// SgtPeppers CD
@Component
public class SgtPeppers implements CompactDisc{

    @Override
    public void play() {
        System.out.println("Sgt. Pepper's Lonely Hearts Club Band is playing");
    }
}

// 播放器
public interface MediaPlayer {
    void play();
}

// CD播放器
@Component
public class CDPlayer implements MediaPlayer{

    private CompactDisc cd;
	
    
    //  -----------------setter方法注入---------------------
    // 注入的CompactDisc为接口,接口注入通常采用setter注入的方式完成
    // --------------------接口注入-------------------------
    @Autowired
    public void setCd(CompactDisc cd) {
        this.cd = cd;
    }

    @Override
    public void play() {
        cd.play();
    }
}

// 配置类
@Configuration
@ComponentScan // 扫描当前包及其子包下的所有组件
public class CDPlayerConfig {
}

// main
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CDPlayerConfig.class);
        CDPlayer cdPlayer = context.getBean(CDPlayer.class);
        cdPlayer.play();
    }
}

构造函数注入

采用自动装配方式

// CD播放器
@Component
public class CDPlayer implements MediaPlayer{
	
    private CompactDisc cd;
	
    // -----------------构造函数注入---------------------
    @Autowired
    public void CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }

    @Override
    public void play() {
        cd.play();
    }
}

接口注入

采用自动装配的方式

// CD播放器
@Component
public class CDPlayer implements MediaPlayer{

    private CompactDisc cd;
	
    
    //  -----------------setter方法注入---------------------
    // 注入的CompactDisc为接口,接口注入通常采用setter注入的方式完成
    // --------------------接口注入-------------------------
    @Autowired
    public void setCd(CompactDisc cd) {
        this.cd = cd;
    }

    @Override
    public void play() {
        cd.play();
    }
}

字段(Field)注入

@Component
public class CDPlayer implements MediaPlayer{
    
	//------------------------字段注入-------------------------
    @Autowired
    private CompactDisc cd;

    @Override
    public void play() {
        cd.play();
    }
}

四、切面编程(AOP)

1、基本概念

AOP面向切面编程是一种编程思想,将贯穿于多个应用对象的逻辑抽象成单独的模块,减少代码的重复性。

2、注解定义切面

使用javaConfig来配置

// 1、定义表演接口
public interface Performance {
    void perform();
}

// 2、戏曲为表演的实现类
public class Xiqu implements Performance{
    @Override
    public void perform() {
        System.out.println("表演戏曲");
    }
}

// 3、为表演配置切面

// ======================无切点===============================
@Aspect
public class Audience {

    @Before("execution(**demo1.Performance.perform(..))")
    public void silenceCellPhones() {
        System.out.println("Silencing cell phones");
    }

    @Before("execution(**demo1.Performance.perform(..))")
    public void takeSeats() {
        System.out.println("Taking seats");
    }

    @After("execution(**demo1.Performance.perform(..))")
    public void applause() {
        System.out.println("CLAP CLAP CLAP!!!");
    }

    @AfterThrowing("execution(**concert.Performance.perform(..))")
    public void demandRefund() {
        System.out.println("Demanding a refund");
    }
}

// ====================切点简化表达式============================

@Aspect
public class Audience {
    @Pointcut("execution(* AOP.demo1.Performance.perform(..))")
    public void performance(){}

    @Before("performance()")
    public void silenceCellPhones() {
        System.out.println("Silencing cell phones");
    }

    @Before("performance()")
    public void takeSeats() {
        System.out.println("Taking seats");
    }

    @After("performance()")
    public void applause() {
        System.out.println("CLAP CLAP CLAP!!!");
    }

    @AfterThrowing("performance()")
    public void demandRefund() {
        System.out.println("Demanding a refund");
    }

}

// =========================切面环绕通知============================
@Aspect
public class Audience {
    @Pointcut("execution(* AOP.demo1.Performance.perform(..))")
    public void performance(){}

    @Around("performance()")
    public void watchPerformance(ProceedingJoinPoint jp) {
        try {
            System.out.println("Silencing cell phones(Around)");
            System.out.println("Taking seats(Around)");
            jp.proceed();
//            int result = 10/0; // 可以抛出异常
            System.out.println("CLAP CLAP CLAP!!!(Around)");
        } catch (Throwable e) {
            System.out.println("Demanding a refund(Around)");
        }
    }
}

// 4、配置文件
@Configuration 
@EnableAspectJAutoProxy  // 开启AOP代理
public class AOPConfig {

    @Bean
    public Audience audience(){
        return  new Audience();
    }

    @Bean
    public Xiqu xiqu(){
        return new Xiqu();
    }
}


// 5、运行测试
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AOPConfig.class);
        Performance xiqu = (Performance) context.getBean("xiqu");
        xiqu.perform();
    }
}

// 6、输出

Silencing cell phones
Taking seats
表演戏曲
CLAP CLAP CLAP!!!

3、定义环绕通知切面

jp.proceed()调用后,执行perform()函数。不调用,只执行切面通知。

@Aspect
public class Audience {
    @Pointcut("execution(* AOP.demo1.Performance.perform(..))")
    public void performance(){}

    @Around("performance()")
    public void watchPerformance(ProceedingJoinPoint jp) {
        try {
            System.out.println("Silencing cell phones(Around)");
            System.out.println("Taking seats(Around)");
            jp.proceed();
//            int result = 10/0; // 可以抛出异常
            System.out.println("CLAP CLAP CLAP!!!(Around)");
        } catch (Throwable e) {
            System.out.println("Demanding a refund(Around)");
        }
    }
}

4、切点方法中含有参数

// 1、定义表演:含参数
public interface Performance {
    void perform(int ticketPrice);
}

// 2、定义戏曲:含参数
public class Xiqu implements Performance {

    @Override
    public void perform(int ticketPrice) {
        System.out.println("表演戏曲,票价:"+ ticketPrice + "元");
    }
}

// 3、定义切面通知:处理参数

//==========================单个参数==================================
@Aspect
public class Audience {
    //接收参数类型+指定参数名称
    @Pointcut("execution(* AOP.demo2.Performance.perform(int))"+"&& args(ticketPrice)")
    public void performance(int ticketPrice){}

    @Before("performance(ticketPrice)")
    public void silenceCellPhones(int ticketPrice) {
        System.out.println("Silencing cell phones");
    }

    @Before("performance(ticketPrice)")
    public void takeSeats(int ticketPrice) {
        System.out.println("Taking seats");
    }

    @After("performance(ticketPrice)")
    public void applause(int ticketPrice) {
        System.out.println("CLAP CLAP CLAP!!!");
    }

    @AfterThrowing("performance(ticketPrice)")
    public void demandRefund(int ticketPrice) {
        System.out.println("Demanding a refund");
    }

}

//==========================多个参数==================================
@Aspect
public class Audience {
    @Pointcut("execution(* AOP.demo2.Performance.perform(int, float))"+"&& args(ticketPrice, startTime)")
    public void performance(int ticketPrice, float startTime){}

    @Before("performance(ticketPrice,startTime)")
    public void silenceCellPhones(int ticketPrice, float startTime) {
        System.out.println("Silencing cell phones");
    }

    @Before("performance(ticketPrice,startTime)")
    public void takeSeats(int ticketPrice, float startTime) {
        System.out.println("Taking seats");
    }

    @After("performance(ticketPrice,startTime)")
    public void applause(int ticketPrice, float startTime) {
        System.out.println("CLAP CLAP CLAP!!!");
    }

    @AfterThrowing("performance(ticketPrice,startTime)")
    public void demandRefund(int ticketPrice, float startTime) {
        System.out.println("Demanding a refund");
    }

}

5、AOP案例(日志管理)

自定义注解

/**
 * 日志注解(该注解目前用于练习切面AOP)
 */
@Target(ElementType.METHOD) // 方法上的注解
@Retention(RetentionPolicy.RUNTIME)  // 运行时注解
@Documented // 生成文档
public @interface LogAnnotation {

        /**
        * 日志描述信息
        */
        String value() default "";
}

定义日志切面

需要导入的包
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>
@Aspect    // 标识为切面类
@Component // 注入IOC容器

/**
* 日志切面逻辑
*/
public class LogAspect {

    @Pointcut("@annotation(com.itsyz.annotation.LogAnnotation)")
    public void logPointCut() {
    }


    /**
     * 前置通知  joinPoint为连接点:业务方法与切面方法的桥梁
     * @param joinPoint
     */
     @Before("logPointCut()")
     public void before(JoinPoint joinPoint) {
         System.out.println("before");
     }
    
	/**
	* 环绕通知
	*/
     @Around("logPointCut()")
        public void around(ProceedingJoinPoint joinPoint) throws Throwable {
            // 日志输出
         String name = joinPoint.getSignature().getName();
         System.out.println("调用了" + name + "方法");
         joinPoint.proceed();
         System.out.println("参数:" + joinPoint.getArgs());
        }

	/**
	* Before与After主要为了查看一下执行顺序
	*/
     @After("logPointCut()")
        public void after(JoinPoint joinPoint) {
            System.out.println("after");
        }
}

开启AOP支持代理

@EnableAspectJAutoProxy //开启AOP支持

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableWebMvc
@EnableAsync //开启异步任务支持(主要)
@EnableAspectJAutoProxy //开启AOP支持
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);

    }
}

具体业务逻辑添加日志

/**
 * 发布事件
 */
@Autowired
ApplicationContext applicationContext;


@LogAnnotation(value = "发布事件")
@GetMapping("/publishEvent")
public void publishEvent() {
    System.out.println(1);
    // 打印当前线程的信息
    System.out.println("执行当前线程的名称1: " + Thread.currentThread().getName());

    Course courses = new Course(1, "Java", "Java.jpg", 100);


    // 发布自定义的课程测试事件
    applicationContext.publishEvent(new CoursesTestEvent(this, courses.getTitle(),courses.getThumb()));
    System.out.println(2);
    System.out.println("执行当前线程的名称2: " + Thread.currentThread().getName());
}

打印结果

调用了previewPdf方法
before
/D:/CodeSpace/ProjectDevelopment/target/classes/
after
参数:[Ljava.lang.Object;@68eef6b4
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
完整全套资源下载地址:https://download.csdn.net/download/qq_27595745/70761177 【完整课程列表】 完整版Java web开发教程PPT课件 Java开发进阶教程 第01章 JavaScript简介以及基本语法(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第02章 Dom模型,控制客户端元素(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第03章 表单验证,常用函数(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第04章 自定义web服务器(共14页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第06章 SERVLET(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第07章 JSP语法及运行过程(共13页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第08章 JSP内置对象(共22页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第09章 jstl、el、java bean(共18页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第10章 过滤器、监听器、自定义标签(共19页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第11章 AJAX实现(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第12章 自定义mvc框架(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第13章 spring ioc aop(共18页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第14章 spring mvc介绍,原理以及搭建(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第15章 spring mvc核心对象拦截器(共26页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第17章 自定义orm框架(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第18章 mybatis框架的搭建以及应用(共13页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第19章 mybatis高级应用(共21页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第20章 数据库连接池,缓存(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第22章 常用框架的介绍以及环境搭建(共16页).pptx JS课程案例ebookHTML\网上书店需求文档.doc

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值