Spring学习笔记:IOC控制反转、AOP面向切面

news2024/11/26 18:26:33

挺快的,框架这一部分

文章目录

  • 一、Spring概述
    • 入门案例
      • 导入依赖包
      • 在src下写配置文件
      • 创建普通类和测试类
  • 二、IOC(控制反转)
    • 2.1 IOC bean 的XML操作(创建对象,注入属性
    • 2.2 IOC bean 的 注解 操作
  • 三、AOP(面向切面)
    • 3.1 切入点表达式
    • 3.2 xml 实现AOP
    • 3.3 注解实现AOP


一、Spring概述

轻量级的 开源的 J2EE框架

IOC: 将创建对象的过程交给Spring来管理[控制反转]

AOP: 面向切面编程,不修改源代码的情况让你的程序增强.

Spring框架的特点

简化开发
aop的支持
方便和其他的框架进行整合
方便进行事务操作

入门案例

导入依赖包

在src下写配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">
    
</beans>

创建普通类和测试类

public class User implements Serializable {
    public void sayHello(){
        System.out.println("Hello Java之神!");
    }
}

在上面配置文件的beans标签里面写bean标签

//id是起个名字,class是类名路径
<bean id="user" class="User"/>

在测试类中调用sayHello方法

    @Test
    public void testBean(){
		//获取配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//调用获得实例
        User user = applicationContext.getBean("user", User.class);
		//调用实例的方法
        user.sayHello();
    }

二、IOC(控制反转)

IOC底层

  • 1.xml解析
  • 2.工厂模式
  • 3.反射

入门案例就是一个控制反转的例子,就是把创建对象的过程交给对象工厂。

Spring 提供IOC实现一共有两种方式:

BeanFactory(了解

是框架内部使用的接口,不提供给开发者 加载配置文件的时候不会创建对象,只有获取对象的时候才会创建。

ApplicationContext(重点
这个是面对开发者的,是BeanFactory接口的子接口,功能更强大。 加载配置文件的时候就会将对象创建出来。

2.1 IOC bean 的XML操作(创建对象,注入属性

属性注入

<!--  set注入  -->
    <bean id="user1" class="User">
        <property name="name" value="我是set注入"/>
        <property name="id" value="1"/>
    </bean>
    
<!--  构造注入  -->
    <bean id="user2" class="User">
        <constructor-arg name="id" value="2"/>
        <constructor-arg name="name" value="我是构造注入"/>
    </bean>

<!--  p 命名空间注入 ( -->
    <bean id="user3" class="User" p:id="3" p:name="我是p 命名空间注入"/>

级联赋值

<!--  级联赋值  -->
    <!--  第一种方式  -->
    <bean id="emp" class="entity.Emp">
        <property name="name" value="idiot"/>

        <property name="dept">
            <bean class="entity.Dept">
                <property name="name" value="地球人事管理"/>
            </bean>
        </property>
    </bean>
    
    <!--  第二种方式  -->
    <bean id="emp" class="entity.Emp">
        <property name="name" value="idiot"/>
        <property name="dept" ref="dept"/>
    </bean>
    <bean id="dept" class="entity.Dept">
        <property name="name" value="宇宙管理分局"/>
    </bean>

特殊类型处理

public class Demo implements Serializable {
    private String [] strings;
    private List<String> lists;
    private Map<String,String> maps;
    private Set<String> sets;
}
    <bean id="demo" class="entity.Demo">
        <!--处理List-->
        <property name="lists">
            <list>
                <value> list1 </value>
                <value> list2 </value>
            </list>
        </property>
        <!--处理Map-->
        <property name="maps">
            <map>
                <entry key="1" value="map1"/>
                <entry key="2" value="map2"/>
            </map>
        </property>
        <!--处理Array-->
        <property name="Strings">
            <array>
                <value> String1 </value>
                <value> String2 </value>
            </array>
        </property>
        <!--处理set-->
        <property name="sets">
            <set>
                <value> set1 </value>
                <value> set2 </value>
            </set>
        </property>
    </bean>

scope=“prototype” 多实例
scope=“singleton” 默认情况 单实例
例子

bean生命周期:

    1. 执行无参构造
    1. 执行set方法设置值
    1. 执行初始化方法(init-method
    1. 获取bean的实例对象
    1. 执行销毁的方法 (destroy-method

自动装配autuwire

  • byName : 根据属性名注入,要求注入bean的id 值要和类的属性名保持一致!!
  • byType : 根据类型注入

2.2 IOC bean 的 注解 操作

Spring框架中提供的关于创建bean的注解 :
@Component
@Service
@Controller
@Repository

四个注解的功能是一样的,都可以用来创建bean的实例

@Autowired 自动配置

@Service
public class Emp implements Serializable {
    private String name;
    @Autowired //这个注解可以自动装配默认采用 byType,即会寻找该类的bean自动注入,不存在的话会抛出异常
    private Dept dept;
}

使用注解要先扫描

<context:component-scan base-package="entity"/>

三、AOP(面向切面)

AOP底层是动态代理

  1. 有接口 使用jdk动态代理
  2. 无接口 使用cglib动态代理

AOP 术语
连接点:

类里面的哪些方法可以被增强,那么这个方法称为连接点

切入点:

实际被真正增强的方法,称为切入点

切面:

把通知应用到切入点的过程称为切面

通知[增强]:

实际增强的逻辑部分称为通知

通知的类型:

  • 前置通知
  • 后置通知
  • 环绕通知
  • 异常通知
  • 最终通知
准备开发:
   Spring的aop是基于 AspectJ 实现aop操作的
   AspectJ 不是Spring的组成部分,独立的AOP框架,将AspectJ 和Spring框架一起使用,进行AOP操作。

3.1 切入点表达式

execution([访问修饰符][返回值类型][类的全路径][方法名][(形参列表)])

execution(* entity.Person.song(..))

3.2 xml 实现AOP

    <bean id="person" class="entity.Person"/>
    <bean id="personProxy" class="entity.PersonProxy"/>

    <aop:config>
        <aop:pointcut id="p" expression="execution(* entity.Person.song(..))"/>
        <aop:aspect ref="personProxy">
            <aop:before method="before" pointcut-ref="p"/>
            <aop:after method="after" pointcut-ref="p"/>
            <aop:around method="around" pointcut-ref="p"/>
            <aop:after-returning method="afterReturning" pointcut-ref="p"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="p"/>
        </aop:aspect>
    </aop:config>

3.3 注解实现AOP

还是要先扫描

<context:component-scan base-package="entity"/>

然后要打开自动代理

<aop:aspectj-autoproxy/>

代理类

@Component
@Aspect //这个不要忘记了,要确定切面
public class PersonProxy {

    @Before("execution(* entity.Person.song(..))")
    public void before(){
        System.out.println("唱前准备:前置通知");
    }

    @After("execution(* entity.Person.song(..))")
    public void after(){
        System.out.println("散伙!:最终通知");
    }

    @Around("execution(* entity.Person.song(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("立体音响:环绕通知前半场");
        proceedingJoinPoint.proceed();
        System.out.println("立体音响:环绕通知后半场");
    }

    @AfterReturning("execution(* entity.Person.song(..))")
    public void afterReturning(){
        System.out.println("唱后收拾:后置通知");
    }

    @AfterThrowing("execution(* entity.Person.song(..))")
    public void afterThrowing(){
        System.out.println("突发状况!开始处理!:异常通知");
    }
}

学完了?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1578433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《UE5_C++多人TPS完整教程》学习笔记31 ——《P32 角色移动(Character Movement)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P32 角色移动&#xff08;Character Movement&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译者&…

用国内版Devin:DevOpsGPT开发一个简易官网

前言&#xff1a; 世界上第一个AI程序员Devin想必已经给大家带来了不小的震撼&#xff0c;这种L4级的技术也许已经昭示着AGI离我们或许真的不远了。 这里先给大家普及一个概念&#xff1a; L4是谷歌对AGI划分的第四个等级&#xff0c;把代码丢给 AI 改这个是 L1 或者 L2 级别的…

CentOS7安装Docker及禅道

https://blog.csdn.net/weixin_46453070/article/details/136183615?ops_request_misc%257B%2522request%255Fid%2522%253A%2522171246925816800222886233%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id171246925816800222886233&biz_i…

基于RTThread的学习(三):正点原子潘多拉 QSPI 通信 W25Q128 实验

1、基于芯片创建工程 2、QSPI配置 2.1、RTThing_setting 设置组件 2.2、配置board.h 文件 2.3、cubemx生成QSPI的硬件初始化代码&#xff1b;HAL_QSPI_MapInit; 这里注意&#xff1a;你所买的开发板对应的qspi 连接的是否是cubemx 上边显示的&#xff0c;如果不是你需要将引脚…

Spring Security——13,认证成功失败注销成功处理器

认证成功&&失败&&注销成功处理器 说明&#xff1a;一、认证成功处理器1.1 自定义成功处理器1.2 配置自定义成功处理器 二、认证失败处理器2.1 自定义失败处理器2.2 配置自定义失败处理器 三、登出成功处理器3.1 自定义登出处理器3.2 配置登出处理器 四、完结撒…

聊一聊,JMeter分布式性能测试!

在做后端服务器性能测试中&#xff0c;我们会经常听到’分布式’。但你是否了解分布式呢&#xff1f;今天&#xff0c;我们就来给大家讲讲&#xff0c;在企业实战中&#xff0c;如何使用分布式进行性能测试&#xff0c;实战过程中&#xff0c;又有哪些地方要特别注意&#xff1…

Inotify

一、关于Inotify linux内核的inotify机制 可以监测文件系统的变动情况&#xff0c;并做出通知响应 二、关于inotify 使用inotify通知接口&#xff0c;可以用来监控文件系统的各种变化情况&#xff0c;可以非常方便地实现文件异动告警、增量备份&#xff0c;并针对目录或文件的…

transformer上手(1) —— transformer介绍

1 起源与发展 2017 年 Google 在《Attention Is All You Need》中提出了 Transformer 结构用于序列标注&#xff0c;在翻译任务上超过了之前最优秀的循环神经网络模型&#xff1b;与此同时&#xff0c;Fast AI 在《Universal Language Model Fine-tuning for Text Classificat…

烤羊肉串引来的思考--命令模式

1.1 吃羊肉串&#xff01; 烧烤摊旁边等着拿肉串的人七嘴八舌地叫开了。场面有些混乱&#xff0c;由于人实在太多&#xff0c;烤羊肉串的老板已经分不清谁是谁&#xff0c;造成分发错误&#xff0c;收钱错误&#xff0c;烤肉质量不过关等。 外面打游击烤羊肉串和这种开门店做烤…

Windows系统下安装java开发环境所需的JDK开发工具包

目录 一、JDK开发工具包下载二、安装三、环境变量配置3.1 添加安装包路径3.2 添加lib路径3.3 添加bin目录 四、检查是否安装成功五、总结 一、JDK开发工具包下载 官网地址&#xff1a;JDK下载 打开网址后有多个版本的JDK&#xff0c;学者根据自己电脑需求选择对应版本下载。如…

类,构造,this,static

第1关&#xff1a;什么是类&#xff0c;如何创建类 100 任务要求参考答案 任务描述相关知识 什么是类怎么定义类创建对象并且使用对象的属性和方法编程要求测试说明 任务描述 本关任务&#xff1a;创建一个类和一个对象&#xff0c;调用这个对象的属性和方法。 相关知识 …

34-5 CSRF漏洞 - CSRF分类

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 1)GET 类型 传参: 参数连接在URL后面 POC构造及执行流程: 构造URL,诱导受害者访问点击利用利用标签进行攻击: 构造虚假URL,在链接上添加payload抓包获取数据包,通过CSRF POC…

解决Xshell连接Linux虚拟机速度慢问题

我们频繁更换网络环境时&#xff0c;可能会发现xshell连接Linux虚拟机的速度变得很慢 为什么呢&#xff1f; 因为ssh的服务端在连接时会自动检测dns环境是否一致导致的 我们把它修改为不检测即可 修改文件位置&#xff1a; vi /etc/ssh/sshd_config 把 #UseDNS yes 修改…

Redis7(二)数据类型及其用法

一、概述 命令不区分大小写&#xff0c;key区分大小写 数据类型针对value String List Set Hash ZSet bitmap GEO HyperLogLog Stream bitfield 二、String <K,V> 1、设值/取值 getrange key index1 index2 getrange key 0 -1//获取所有的值 SETRANGE KEY_N…

代码随想录第34天| 1005.K次取反后最大化的数组和 134. 加油站 135. 分发糖果

1005.K次取反后最大化的数组和 1005. K 次取反后最大化的数组和 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 贪心算法&#xff0c;这不就是常识&#xff1f;还能叫贪心&#xff1f;LeetCode&#xff1a;1005.K次取反后最大化的数组和_哔哩哔…

如何选择苹果iOS系统的企业签名分发平台

哈喽&#xff0c;大家好呀&#xff0c;淼淼有和大家见面啦&#xff0c;前两期讲了分发内测的一些相关知识&#xff0c;这一期咱们来聊聊企业签名分发平台的相关知识。最近移动应用市场的竞争一天比一天要激烈&#xff0c;许多做开发的小伙伴们都在为此发愁&#xff0c;愁着该怎…

不要再使用 @Builder 注解了!有深坑呀!

曾经&#xff0c;我在《千万不要再随便使用 lombok 的 Builder 了&#xff01;》 一文中提到 Builder 注解的其中一个大坑会导致默认值失效&#xff01; 最近阅读了 《Oh !! Stop using Builder》 发现 Builder 的问题还不止一个&#xff0c;Builder 会让人误以为是遵循构建器…

java的封装

在Java中&#xff0c;封装是面向对象编程中的一种重要概念&#xff0c;它指的是将数据和方法打包在一个单一的单位&#xff08;类&#xff09;中&#xff0c;并对外部隐藏对象的内部细节。封装通过将类的成员变量声明为私有的&#xff0c;并提供公共的方法来访问和修改这些变量…

数据库关系模式三元及以上分解无损连接判断(表格法)

例题 1.首先构造初始表&#xff0c;如下表所示。 A B C D E ABC a1 a2 a3 b14 b15 CD b21 b22 a3 a4 b15 DE b31 b32 b33 a4 a5 2.遍历函数依赖&#xff0c;对AB→C&#xff0c;因各元组的第一、二列没有相同的分量&#xff0c;所以表不改变。 3.由C→D…

【日常记录】【JS】getComputedStyle 获取DOM的最终样式值

文章目录 1、介绍2、getComputedStyle3、链接 1、介绍 Window.getComputedStyle()方法返回一个对象&#xff0c;该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有 CSS 属性的值。私有的 CSS 属性值可以通过对象提供的 API 或通过简单地使用 CSS 属性…