8.框架Spring

news2025/1/16 20:16:43

一、基本概念

        Spring 是 Java EE 编程领域的一款轻量级的开源框架,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,它的目标就是要简化 Java 企业级应用程序的开发难度和周期。

        导入依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.22</version>
</dependency>

二、IoC容器

        在传统的 Java 应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过 new Object() 的方式将后者的对象创建出来,然后才能实现属性或方法的调用。为了方便理解和描述,我们可以将前者称为“调用者”,将后者称为“被调用者”。也就是说,调用者掌握着被调用者对象创建的控制权。
        但在 Spring 应用中,Java 对象创建的控制权是掌握在 IoC 容器手里的,其大致步骤如下:

  1. 开发人员通过 XML 配置文件、注解、Java 配置类等方式,对 Java 对象进行定义,例如在 XML 配置文件中使用 <bean> 标签、在 Java 类上使用 @Component 注解等。
  2. Spring 启动时,IoC 容器会自动根据对象定义,将这些对象创建并管理起来。这些被 IoC 容器创建并管理的对象被称为 Spring Bean。
  3. 当我们想要使用某个 Bean 时,可以直接从 IoC 容器中获取(例如通过 ApplicationContext 的 getBean() 方法),而不需要手动通过代码(例如 new Obejct() 的方式)创建。

        IoC 带来的最大改变不是代码层面的,而是从思想层面上发生了“主从换位”的改变。原本调用者是主动的一方,它想要使用什么资源就会主动出击,自己创建;但在 Spring 应用中,IoC 容器掌握着主动权,调用者则变成了被动的一方,被动的等待 IoC 容器创建它所需要的对象 bean 。
        这个过程在职责层面发生了控制权的反转,把原本调用者通过代码实现的对象的创建,反转给 IoC 容器来帮忙实现,因此我们将这个过程称为 Spring 的“控制反转”。

        BeanFactory 是 IoC 容器的基本实现,也是 Spring 提供的最简单的 IoC 容器,它提供了 IoC 容器最基本的功能,由 org.springframework.beans.factory.BeanFactory 接口定义。

@Test
public void test1() {

    DefaultListableBeanFactory factory=new DefaultListableBeanFactory();

    XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(factory);

    reader.loadBeanDefinitions("beans.xml");

    User user= (User) factory.getBean("user");
    
    System.out.println(user);

}

        ApplicationContext 是 BeanFactory 接口的子接口,是对 BeanFactory 的扩展。ApplicationContext 在 BeanFactory 的基础上增加了许多企业级的功能,例如 AOP(面向切面编程)、国际化、事务支持等。

@Test
public void test2() {
    //加载类路径xml
    ApplicationContext context1=new ClassPathXmlApplicationContext();
    //加载指定路径xml
    ApplicationContext context2=new FileSystemXmlApplicationContext();
    //加载注解
    ApplicationContext context3=new AnnotationConfigApplicationContext();
    //混合方式加载bean
    ApplicationContext context4=new GenericApplicationContext();

}

三、Bean

        Spring开发中主要是对Bean的配置,Bean的常用配置一览如下:

        Bean 属性注入,简单点说就是将属性注入到 Bean 中的过程,而这属性既可以普通属性,也可以是一个对象(Bean)。Spring 主要通过以下 2 种方式实现属性注入:1.构造函数注入;2.设值注入。

        构造注入:

<!--name:按变量名注入
    type:按类型注入
    index:按索引注入
    value:注入值
    ref:注入bean-->
<bean id="user" class="com.lulu.entity.User">
    <constructor-arg type="java.lang.Long" value="1"/>
    <constructor-arg index="1" value="lulu"/>
    <constructor-arg name="age" value="20"/>
    <constructor-arg name="gender" value="1"/>
    <constructor-arg name="book" ref="book"/>
</bean>

         设值注入:

<!--name:按变量名注入
    value:注入值
    ref:注入bean-->
<bean id="user" class="com.lulu.entity.User">
    <property name="id" value="1"/>
    <property name="name" value="lulu"/>
    <property name="age" value="20"/>
    <property name="gender" value="1"/>
    <property name="book" ref="book"/>
</bean>

        特殊类型注入:

<!--array:数组注入
    list:列表注入
    set:集合注入
    map:键值对注入
    properties:键值对注入
    value:注入值
    ref:注入bean-->
<bean id="user" class="com.lulu.entity.User">
    <property name="strings">
        <array>
            <value>string</value>
        </array>
    </property>
    <property name="list">
        <list>
            <ref bean="book"/>
        </list>
    </property>
    <property name="set">
        <set>
            <value>set</value>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="map" value="map"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="prop">prop</prop>
        </props>
    </property>
</bean>

         为了简化开发,可以使用注解进行bean配置(需要指定扫描包):

@Data//lombok
@NoArgsConstructor
@AllArgsConstructor
@Component("user")//声明为普通bean,衍生 @Controller:web层bean, @Service:service层bean, @Repository:dao层bean
@Scope("prototype")//bean模式
@Lazy//延迟加载
public class User {
    @Value("1")//值注入
    private Long id;
    @Value("lulu")
    private String name;
    @Value("20")
    private Integer age;
    @Value("1")
    private Integer gender;
    @Resource(name = "book",type = Book.class)//按名称或类型注入
    @Autowired//按类型注入
    private Book book;


    @PostConstruct//初始化方法
    private void postConstruct(){}
    @PreDestroy//销毁前方法
    private void preDestroy(){}
}

        如果完全不使用xml文件进行配置,需要自定义配置类,并加入ApplicationContext:

@Configuration//声明为配置类
@ComponentScan("com.lulu.entity")//指定扫描包
public class SpringConfig {

    @Bean//将方法返回对象声明为bean
    public void bean(){}

}

        在测试类中使用自动注入时要注意导入依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.3.22</version>
</dependency>
//@RunWith注解表示运行在Spring容器中,包括controller,service,dao等
@RunWith(SpringJUnit4ClassRunner.class)
//加载spring配置类
@ContextConfiguration(classes = SpringConfig.class)
public class Test1 {
}

四、AOP

        Spring AOP 是 Spring 框架的核心模块之一,它使用纯 Java 实现,因此不需要专门的编译过程和类加载器,可以在程序运行期通过代理方式向目标类织入增强代码。

        导入依赖:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

        在配置文件中需要开启AOP命名空间:

<aop:config>
    <!--配置切入点:指定类方法,切点表达式execution([修饰符] 返回值类型 包名.类名.方法(参数))-->
    <aop:pointcut id="pointcut" expression="execution(void com.lulu.entity.User.sayHello())"/>
    <!--配置切面:指定增强方法与切入点结合-->
    <aop:aspect ref="userAdvice">
        <!--前置增强-->
        <aop:before method="pre" pointcut-ref="pointcut"/>
        <!--后置增强-->
        <aop:after method="post" pointcut-ref="pointcut"/>
        <!--环绕增强-->
        <aop:around method="around" pointcut-ref="pointcut"/>
    </aop:aspect>
</aop:config>

        增强方法有五种类型:

         注解配置AOP需要在配置类声明@EnableAspectJAutoProxy:

@Component
@Aspect//声明为增强类
public class UserAdvice {
    //配置切入点
    @Pointcut("execution(void com.lulu.entity.User.sayHello())")
    public void pointcut(){}

    @Before("pointcut()")
    public void pre(){
        System.out.println("preAdvice");
    }
    @After("pointcut()")
    public void post(){
        System.out.println("postAdvice");
    }
    @Around("pointcut()")
    public void around(){
        System.out.println("aroundAdvice");
    }

}

        事务(Transaction)是基于关系型数据库(RDBMS)的企业应用的重要组成部分。在软件开发领域,事务扮演者十分重要的角色,用来确保应用程序数据的完整性和一致性。作为一款优秀的开源框架和应用平台,Spring 也对事务提供了很好的支持。Spring 借助 IoC 容器强大的配置能力,为事务提供了丰富的功能支持。

        导入依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.3.22</version>
</dependency>

        开启事务需要在配置类上声明@EnableTransactionManagement并配置事务管理器:

@Bean//配置数据源
public DataSource dataSource(){
    DruidDataSource dataSource=new DruidDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql:///libmanagesystem?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
    dataSource.setUsername("");
    dataSource.setPassword("");
    return dataSource;
}
@Bean//配置事务管理器
public PlatformTransactionManager transactionManager(DataSource dataSource){
    DataSourceTransactionManager dataSourceTransactionManager=new DataSourceTransactionManager();
    dataSourceTransactionManager.setDataSource(dataSource);
    return dataSourceTransactionManager;
}

        在需要进行事务管理的类或方法上声明@Transactional即可。@Transactional 注解包含多个属性,其中常用属性如下表。

事务属性说明
propagation指定事务的传播行为。
isolation指定事务的隔离级别。
read-only指定是否为只读事务。
timeout表示超时时间,单位为“秒”;声明的事务在指定的超时时间后,自动回滚,避免事务长时间不提交会回滚导致的数据库资源的占用。
rollback-for指定事务对于那些类型的异常应当回滚,而不提交。
no-rollback-for指定事务对于那些异常应当继续运行,而不回滚。

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

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

相关文章

操作系统(一)

操作系统&#xff08;一&#xff09; 1、什么是操作系统 操作系统是指控制和管理整个计算机系统的硬件与软件资源&#xff0c;合理的组织、调度计算机的工作与资源分配&#xff0c;进而为用户和其他软件提供方便接口与环境的程序集合。操作系统是计算机系统中最基本的系统软件…

Android 深入系统完全讲解(24)

https://blog.csdn.net/weixin_41101173/article/details/80374455 理解了绘制内容&#xff0c;解决了这部分&#xff0c;下来我们来说说关于音视频的其他部分。 所有的文件&#xff0c;都有一个叫做格式的东西存在&#xff0c;MP3&#xff0c;WAV&#xff0c;而处理这个格式的…

zookeeper集群安装

zookeeper集群安装 1. 安装环境介绍 下载地址&#xff1a; http://archive.apache.org/dist/zookeeper/ 安装版本&#xff1a; 3.7.0 安装包&#xff1a; apache-zookeeper-3.7.0-bin.tar.gz 安装目录&#xff1a; /opt 机器IP&#xff1a; 10.28.19.107 10.28.19.108 10…

字符矩阵内单词搜索

单词搜索 问题链接&#xff1a;word search&#xff01;&#xff01;&#xff01; 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通…

【阅读笔记】c++ Primer Plus——第九章

内存模型和命名空间 单独编译 c程序分成三部分 第一部分&#xff1a;包含结构声明和使用这些结构的函数原型(头文件)第二部分&#xff1a;包含与结构有关的函数代码(源代码文件)第三部分&#xff1a;包含调用与结构相关的函数代码(源代码文件)头文件包含了用户定义类型的定义…

FPGA 20个例程篇:19.OV7725摄像头实时采集送HDMI显示(二)

第七章 实战项目提升&#xff0c;完善简历 19.OV7725摄像头实时采集送HDMI显示&#xff08;二&#xff09; 在正式介绍OV7725 CMOS Sensor视频采集前&#xff0c;首先需要去详细说明OV7725的寄存器配置接口&#xff0c;这里有OmniVision公司推出的官方手册 “OV7725_software_…

8个必须掌握的Blender拓扑技巧

组合 3D 模型的过程对后续过程影响很大 - 稍后编辑的难易程度、应用光照和着色器时的外观效果如何、动画时变形的难易程度等等。 一个好的模型对于 CG 管道的所有其他部分的良好运行至关重要。 另一方面&#xff0c;凌乱的拓扑结构会使流程的其余部分成为一场灾难。 你能做些…

IB地理科补习有用吗?

IB地理科的补习如何帮助学生改变学科的表现&#xff1f;这可以从几方面来做分析。 1. 训练 第一是训练。我们老师会按来补习的同学的个人需求、时间和个性&#xff0c;提供很多不同程度的训练&#xff0c;帮助他们建立一个正确的能力系统&#xff08;skill set&#xff09;去应…

二、预训练模型预测(Datawhale组队学习)

文章目录安装配置环境ImageNet预训练图像分类模型预测单张图像-英文载入预训练图像分类模型图像预处理执行图像分类预测预测结果分析ImageNet预训练图像分类模型预测单张图像-中文预训练图像分类模型图像预处理执行图像分类预测预测结果分析ImageNet预训练图像分类模型预测视频…

汽车CAN总线硬件电路原理

根据ISO 11898的定义&#xff0c;物理层被细分成3 个子层&#xff0c;它们分别是物理信令&#xff08;位编码定时和同步&#xff09;、物理媒体连接&#xff08;驱动器和接收器特性&#xff09;和媒体相关接口&#xff08;总线连接器&#xff09;。物理信令子层和数据链路层之间…

打包iOS App并上架到TestFlight测试

开发者账号 首先需要注册一个开发者账号&#xff0c;不然什么都免谈。在手机Apple Developer上注册给钱就行了&#xff0c;个人开发者一年688元。 打包App App开发好后&#xff0c;就可以通过XCode打包。打包前选好版本号&#xff0c;不要跟以前提交的一样&#xff0c;重复的…

亚马逊云科技携手普华永道,助力泉峰集团破解数据治理与使用难题

大数据时代的到来&#xff0c;掀起了企业数字化转型的热潮&#xff0c;对于制造行业的企业来说&#xff0c;除了顺应发展潮流快速开启数字转型之外&#xff0c;以创新思维不断拓展业务广度&#xff0c;对于自身发展也有着格外重要的意义。数字化水平能否与创新发展的脚步保持一…

Acwing---1237.螺旋折线

螺旋折线1.题目2.基本思想3.代码实现1.题目 如下图所示的螺旋折线经过平面上所有整点恰好一次。 对于整点 (X,Y)(X,Y)(X,Y)&#xff0c;我们定义它到原点的距离 dis(X,Y)dis(X,Y)dis(X,Y) 是从原点到 (X,Y)(X,Y)(X,Y) 的螺旋折线段的长度。 例如 dis(0,1)3,dis(−2,−1)9di…

账户系统从0到1搭建

一、什么是账户/账户的作用&#xff1f;账户是记录账户所属人&#xff08;账户主体&#xff09;资产增减变化的载体&#xff0c;简单来说账户系统就是用来记账的&#xff0c;这也是账户系统最核心的功能&#xff0c;在这个基础之上也会根据业务需要衍生出来的其他附属功能。为了…

Kotlin 元编程之 KSP 实战:通过自定义注解配置Compose导航路由

在上一篇 Kotlin 元编程之 KSP 全面突破 中&#xff0c;通过几个设计模式相关的例子来生成代码&#xff0c;其逻辑都比较简单&#xff0c;没有涉及到Android相关的API 业务类&#xff0c;而本文的例子会涉及到使用 Android API 相关的代码。 在之前Jetpack Compose中的导航路由…

【MySQL进阶】MySQL事务隔离与锁机制底层原理万字总结(建议收藏!!)

【MySQL进阶】MySQL事务隔离与锁机制底层原理万字总结&#xff08;建议收藏&#xff01;&#xff01;&#xff09; 参考资料&#xff1a; 美团技术团队&#xff1a;Innodb中事务隔离级别和锁的关系 数据库的锁&#xff0c;到底锁的是什么&#xff1f; 阿里面试&#xff1a;说说…

来给博客除草了:Learned Indexes for a Google-scale Disk-based Database

1. 引言 这是一篇业界发表在NeurlIPS 2020的Wip论文《Google规模的基于磁盘的数据库的学习索引》。自从学习索引祖师爷Tim KraskaMIT在SIGMOD 2018发表了第一篇learned index的工作之后&#xff0c;有关学习索引的paper呈现 increasing trend。目前&#xff0c;较多的工作focu…

Java基础漏洞(四)

&#xff08;1&#xff09;递归调用的内存 我们定义一个类A&#xff0c;在类A中定义方法test来验证递归。在程序中&#xff0c;当条件符合的时候会不断的递归&#xff0c;只有遇到终止条件时才不再递归&#xff0c;然后便会执行递归语句之下的语句。 如以下程序&#xff1a;当…

高效节能 | 智慧灯杆综合管理解决方案

智慧灯杆的应用越来越广泛&#xff0c;园区、景区、道路照明&#xff0c;三站一场等户外场所大规模铺设路灯&#xff0c;通过智慧物联平台远程控制&#xff0c;可以实现高效节能和智能化运维管理。以解决传统运维管理中&#xff0c;不同路线路灯设备控制不统一&#xff0c;设备…

Yjs解析

本文引用自 摸鱼wiki 1. YATA算法解析 YATA算法是Yjs库的核心冲突解决算法&#xff0c;这里主要讲解下这个算法成立的三个规则&#xff1a; 规则1&#xff1a;禁止发生冲突的插入操作之间的origin连线&#xff08;红线&#xff09;发生交叉。 如上图所示&#xff0c;图中展示…