Spring框架IOC和AOP

发布于:2023-01-18 ⋅ 阅读:(170) ⋅ 点赞:(0)

一、什么是Spring

Spring是绿色的开源免费架构,是将各种框架整合在一起。

二、Spring架构

三、Spring框架的IOC

IOC,即控制反转,是将主动创建的方式反转为被动接收,实现代码的解耦。

控制反转(IOC)采用的方法是依赖注入(DI),依赖注入是在Spring当中交由容器来管理对象。

四、Spring框架的优点

1.使用Spring的IOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑;

2.可以提供众多服务,事务管理,WS等;

3.AOP的很好支持,方便面向切面编程;

4.对主流的框架提供了很好的集成支持,如Hibernate、Struts2、JPA等。

5.Spring DI机制降低了业务对象替换的复杂性;

6.Spring属于低侵入,代码污染极低;

7.Spring的高度可开放性,并不强制依赖于Spring,开发者可以自由选择Spring部分或全部;

五、Spring框架的容器

Spring容器是Spring框架的核心,用来管理Bean对象。

Spring容器的两种实现:1.Beanfactory容器 - - 最简单的容器,是Spring容器中最顶层的接口。

                                        2.ApplicationContext容器 - - BeanFactory的子类,拥有丰富的功能。

Spring容器提供的常用方法:1.getBean() -- 获取Bean对象

                                               2.containsBean() -- 判断容器中的指定对象是否存在

                                               3.isprototype() -- 判断容器中的对象是否为非单例对象

                                               4.isSingleton() -- 判断容器中的对象是否为单例对象

ApplicationContext的常用实现类:ClassPathXmlApplicationContext -- Xml配置

                                                        AnnotionConfigApplicationContext -- Spring配置

六、依赖注入(DI)

依赖注入,即Bean对象中的属性值通过IOC容器注入。

依赖注入的方式:

1.属性注入

2.构造方法注入

3.工厂方法注入(很少使用,不推荐)

七、基于注解装配Bean

Spring提供了以下几个注解来完成Bean的自动装配:

@Audowried -- JDK自带注解,根据类型自动装配。

@Qualifier -- JDK自带注解,根据名称自动装配,要和@Audowried搭配使用。

@Resource -- 不是JDK自带注解,根据名称和类型都可以自动装配,必须要导包。

@PostConstrct -- 初始化方法

@PreDestory -- 销毁方法

八、Spring框架的AOP

        AOP(Aspect Oriented Programming)面向切面编程。使得开发者仅仅关注业务逻辑本身的开发,而不用去纠缠于一些如安全、事务等和核心业务逻辑无关,但是又必须用到的通用性功能。

        和OOP(Object Oriented Programming)面向对象编程有些类似。

        AOP和OOP都是一个编程思想,OOP主要功能是封装,类的继承以及多态 ;AOP是将系统分解为不同的关注点(不同的切面)。

九、AOP术语

        切面(Asepect):要实现的交叉的非核心业务功能,组成是通知和切入点。

        连接点(Joinpoint):应用程序执行过程中插入切面的地点,可以是方法调用、异常抛出。

        通知(Advice):通知切面的实际实现代码。

        切入点(Pointcut):定义通知应用在哪些连接点。

        目标对象(Target):被通知的对象。

        代理(Proxy):将通知应用到目标对象后创建的对象。

        织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。

十、AOP通知类型

        通知有5种类型:

        @Before 前置通知,在方法执行前执行 。

        @After 后置通知,在方法执行后执行,方法无论有没有异常都会执行。

         @AfterReturning 返回通知,在方法正常结束之后执行。       

         @AfterThrowing 异常通知,在方法抛出异常后执行。

         @Around 环绕通知,围绕着方法执行

十一、书写AOP代码的具体实现

1.导入依赖

<dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-context</artifactId>

        <version>5.2.7.RELEASE</version>

</dependency>

<dependency>

        <groupId>org.aspectj</groupId>

        <artifactId>aspectjweaver</artifactId>

        <version>1.9.4</version>

</dependency>

2.在Spring中心配置类中,加入注解@EnableAspectJAutoProxy,开启AOP支持。

3.创建切面--就是一个带有@Aspect注解的类

@Aspect // 标识此类为切面

@Component
public class FirstAspect {
   // 书写通知和切入点
}

4.定义切入点

/*
        使用 @Pointcut 定义一个切入点
        注意:1.切入点定义需要搭配方法
             2.返回值类型必须是void,访问修饰符是private
        在定义切入点时,需要指明切入点是连接哪一个连接点,此时需要使用切入点(execution)表达式去说明
        execution语法格式:
            execution(返回值类型 类的全限定名.方法名称(参数列表))
            返回值类型: * -- 表示可以为任何返回值,如果返回值为对象需要写全限定类名
            类的全限定名:包名 + 类名 * -- 可以为任何类

            特殊含义符号:* --表示匹配任意数量的字符
                       .. 匹配任何数量的字符重复,
                           如果在全限定类名处使用..,则表示匹配任何数量的子包
                           如果在方法参数中使用..,则表示匹配任意数量参数
     */
    @Pointcut("execution(* com.project..UserService.t*(..))")
    private void myPointcut(){}

5.定义通知

    @Pointcut("execution(* com.project..ManService.*(..))")
    private void pointcut(){}

// @Before 前置通知,在方法执行前执行
    @Before("pointcut()")
    public void before(){
        System.out.println("这是前置通知");
    }

// @After  后置通知,在方法执行后执行,方法无论有没有异常都会执行
    @After("pointcut()")
    public void after(){
        System.out.println("这是后置通知");
    }

// @AfterReturning 返回通知,在方法正常结束之后执行
    @AfterReturning("pointcut()")
    public void afterReturning(){
        System.out.println("这是方法正常结束之后的--返回通知");
    }

// @AfterThrowing 异常通知,在方法抛出异常后执行
    @AfterThrowing("pointcut()")
    public void afterThrowing(){
        System.out.println("方法出现异常--异常通知");
    }

// @Around 环绕通知,围绕着方法执行
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) {
/*      ProceedingJoinPoint 的proceed方法去执行目标方法
        ProceedingJoinPoint 的getSignature方法获取目标方法的信息
        ProceedingJoinPoint 的getTarget方法获取目标对象*/
        Object obj = null;
        try {
            System.out.println("环绕前通知" + joinPoint.getSignature());
            Object target = joinPoint.getTarget();
            System.out.println(target.getClass().getSimpleName());
            obj = joinPoint.proceed();// 执行目标方法
            System.out.println("环绕后通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return obj;
    }

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到