仿牛客网项目实战3:Spring入门

简介: spring一般指的是一个全家桶。

Spring


spring一般指的是一个全家桶。

84f2a0b1e8227aa3cd6545cbee003471_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

项目中只有浏览器一个客户端,所以项目中DataFlow是用不上的。

只是做基本的web开发springboot就可以了,build anything。

如果想做微服务那么就用springcloud,能够协调一切coordinate anything。

如果想做更多的客户端及集成,spring cloud data flow可以连接一切。


这些都是基于Spring Framework框架的。


Spring Framework


66c13a8923c9df82fae38b1fdc807d63_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_15,color_FFFFFF,t_70,g_se,x_16.png

IoC、AOP都是用来管理对象的思想。


Spring Core的核心

IoC/AOP

都是管理对象的思想,IoC是面向对象,AOP是面向切面的思想,所以有这两个思想能够管理一切对象。

Spring Data Access

用来管理数据库事务。

Web Servlet

使用SpringMVC来管理Web开发。

Integration继承

用来集成Email、AMQP消息队列、Security安全控制等等。

IoC

Spring所有功能都是可以说以IoC为基础的。


Inversion of Control

控制反转,是一种面向对象编程的思想。

通常关联对象是new一个对象a,然后a.setB创建B的对象,但是缺点就是A和B进行了耦合,如果项目变大了,那么就不方便维护。所以IoC是为了解决耦合度的问题。

f915903d008a04572d3af2dc60bec1bf_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

ioc是靠 Dependency Injection来实现的,即依赖注入。

而依赖注入是ioc容器实现的关键,本质上就是工厂。

e1ee26865873157c5c96eef67f865efc_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_13,color_FFFFFF,t_70,g_se,x_16.png

bean与bean之间的关联是在配置中体现的,降低了耦合度。

34044cb093a87750fc0e11ed1ea741a7_c3817398b34d4868b34488c2f9969a9c.png

@springbootapplication这个注解是由其他注解组成的。

fb97f7f7c32c751db889f078d56d517b_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_18,color_FFFFFF,t_70,g_se,x_16.png

按住control点进去可以发现构成这个注解的注解有哪些。

@componentscan就是配置类扫描,哪些类能被扫描呢,就是需要@Controller和@Service、@Repository等四个配置才能被自动扫描到。

如果是业务组件就需要@Service组件才能被扫描,如果是控制组件就需要@Controller。

【重要注解:①@controller(请求)、@Repository(数据库)、@Service(业务)和@Component(任意调用)可以使得spring容器扫描bean;可以直接使用application.getbean()的方式获得,也可以使用@Autowired依赖注入的方式;如果bean出现重名,可以使用name将其区分开,也可以使用@primary设置其优先级;默认创建的bean对象都是单例的,如果需要改变不是单例@singlone可以写成@prototype改变成多例的。】


如何证明这个容器存在呢,可以这么证明:

0ba871fe3f7041ed6b3e6fdec748a80c_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

这样子控制台可以看到输出了这个容器,是可见的,是存在的。那么如何运用这个容器去管理Bean呢?


现在写一个bean,现在假设要访问数据库,那么我建一个包专门用来管理访问数据库,这个包下建立接口等等。

377418d3d207fd1bccf13a0cc30daf06_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_18,color_FFFFFF,t_70,g_se,x_16.png


接口不能直接用,还得加一个接口的实现类。

然后增加这个接口的具体实现方法。


同时注意在类上加上注解,让程序自动扫描。

0b809ff1f3c810fc5c43f269386c4ef1_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

然后就可以从容器中获取到这个Bean了。

6a20a86607fdbd03af110dfaef0f13cb_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png


这样就成功获取到了Bean,并得到了结果。

这样做的好处:再次通过一个实例来观察。

846845d9840933e743e088287c089bbd_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_17,color_FFFFFF,t_70,g_se,x_16.png


做完上面这一张图需要注意加注解,同时这个时候因为我们是getBean去获取,那么此时满足条件的就有两个了,Bean容器就不知道给你哪一个了。

然后这个时候只需要在希望得到的Bean加一个注解就可以优先得到了。

91b7da8d8242abf042cbd76aef613998_bf36c95c23eb4e398da7013b50f85940.png

调用的Bean是依赖的接口,不依赖本身,则是面向接口的思想,就比较方便,但是也可能会带来一个问题,如果某一块不想要MyBatis,那么就需要强制容器进行返回就可以了。

27b91491f70d160410744f8a67e2242d_137b2eccf9b3478da61ad4a19848fa1d.png

除了上面这个方法,还可以通过加前缀强制转型。

ad00a5c3254957aed67ef2c8958b3ef1_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png


现在如果该多了一个service层,那么可以如 下图一样进行添加。

现在希望容器管理这个Bean销毁和初始化那些方法,那么想要容器调用这些方法需要添加@PostConstruct方法就可以了。通常在构造器后进行调用。

0321c37ba40f03fa39aa6c85dac2f468_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

557ea21009ea62e8fcd3bbede65df41c_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png


现在在测试类进行测试演示。

c613a69482fcce7612155b4c54573f80_dc57ed364ee4404eab60563d4028ac01.png

然后可以发现在控制台打印了这些方法。

27ebf311ef0e031d5251ebe6979cf873_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

然后通过打印台可以看出,这些Bean都是实例化一次的,只实例一次的。

开始被实例、初始化,然后结束后销毁。

就算调用两次,控制台也是出来一次的。

可以看出是单例的。


如果不希望是单例的,希望整个容器中有多个,那么就需要加一个注解。

4be087167cb8f554aac4a79d134c0321_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_13,color_FFFFFF,t_70,g_se,x_16.png

这样每次访问该Bean的时候都会加一个实例。

但是通常情况下都是单例的情况。


以上都是管理自己的Bean,那么如果想调用第三方的话,那么就需要自己写一个配置类,装配一个第三方的Bean。

配置类可以建一个包 config包。

5d1a125bdf2adbab681d00de76d22619_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

同时需要注意下图中的方法名就是Bean的名字。

14b30f7b8177776ab409bdef8209cd5d_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

这个时候也就说这个方法的返回类型将被装配到容器里进行反复运用。

然后再 在测试类中进行测试,再添加一个测试方法。

先声明类型然后进行getBean就可以了。下图中调用这个对象去初始化一个当前时间。

0a0e3ceca09fd2967dcaf9fee8da6417_fd742b9ce5224345bad5c4130c54e1af.png

f20c786beb74a084f010dbd6efcd7c8f_d54729a00ebe4d4ab2049887d3f85e90.png

上述讲的都是主动调用容器的方法。

但是一般是自动注入容器等。接下来讲 依赖注入。


只需要声明给当前的Bean注入Alpdao就可以了。

那么注入的话需要用到@Autowired注解。

然后加在一个成员变量之前。

那么就是说,希望容器把alphadao注入给这个属性,给我们直接使用就可以了。(DI依赖注入)

502bdc08cd524847d63a47d263a07a7a_9dd64d767580436094bff06a20fd33f7.png

发现可以打印出结果的。

e35b7ded13e16a2e46b4271585b0ce28_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

同理,alphaService也是可以的,SimpleDateFormat也是可以的。

71994c30bc6cb3d2e3aae1aaf40a7218_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_14,color_FFFFFF,t_70,g_se,x_16.png

729a8ab955d82622d12aa6d177e01d98_6f5c901067d846ff8d8c517475d90cc9.png

这个时候都取到了。

但如果想改注入的东西,比如说alphadao不要alphadao而是hibernate,那么就可以添加一个注释就可以了。(即忽视优先级)

6935d814449c1f866b621d85a88eb737_695a7767a3aa45df9fd5468a9e9e3d70.png

实际业务中:controller处理浏览器的请求,来调用service处理业务,然后service调用dao处理。彼此互相依赖的,他们的关系就可以通过依赖注入实现。

比如说现在需要注入alphadao给alphaserrvice。那么就可以在处理业务的时候调用service了。

b24b86b8be6d377749578222502dd957_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

然后写一个方法模拟查询的业务就可以了。

2e8bdebfec21e0b3d2c108978b5e3ee1_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

然后再controller中将service注入给他,然后处理一个查询请求的方法就可以了。

583cbf725f2af7daf0a90532d93bdbec_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_20,color_FFFFFF,t_70,g_se,x_16.png

dcc4351ce1901630c42f51632cc993d5_4b140fbace6b4ac7bba7b144066a18aa.png


整理一下:首先调用controller,然后controller调用service中的find方法,然后find方法中又调用alohadao的方法,然后就是这么实现的。通过这样的例子理解DI的概念。

通过容器统一的管理,降低Bean之间的耦合度。

(可以看到,在controller层中,我们调用了service层的代码,却不是直接new一个对象,而是用@Autowired注解,并在类上使用了@Controller注解,这些注解帮助我们自动配置并注入对象,我们在使用时就不用new对象,从而减少代码耦合。)

ec003ebac9d39b02b98a2abf493a2fcb_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_16,color_FFFFFF,t_70,g_se,x_16.png

038764693706f2dc8f89a06f56a7a696_watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA572R5LqL6ZqP6aOOMjAxNw==,size_19,color_FFFFFF,t_70,g_se,x_16.png

相关文章
|
2月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
2月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
2月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
2月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
2月前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
2月前
|
XML Java 数据格式
Spring5入门到实战------5、IOC容器-Bean管理(三)
这篇文章深入探讨了Spring5框架中IOC容器的高级Bean管理,包括FactoryBean的使用、Bean作用域的设置、Bean生命周期的详细解释以及Bean后置处理器的实现和应用。
Spring5入门到实战------5、IOC容器-Bean管理(三)
|
2月前
|
XML Java 数据格式
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
这篇文章是Spring5框架的实战教程,主题是IOC容器中Bean的集合属性注入,通过XML配置方式。文章详细讲解了如何在Spring中注入数组、List、Map和Set类型的集合属性,并提供了相应的XML配置示例和Java类定义。此外,还介绍了如何在集合中注入对象类型值,以及如何使用Spring的util命名空间来实现集合的复用。最后,通过测试代码和结果展示了注入效果。
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
|
2月前
|
SQL 数据库
Spring5入门到实战------13、使用JdbcTemplate操作数据库(批量增删改)。具体代码+讲解 【下篇】
这篇文章是Spring5框架的实战教程,深入讲解了如何使用JdbcTemplate进行数据库的批量操作,包括批量添加、批量修改和批量删除的具体代码实现和测试过程,并通过完整的项目案例展示了如何在实际开发中应用这些技术。
Spring5入门到实战------13、使用JdbcTemplate操作数据库(批量增删改)。具体代码+讲解 【下篇】
|
2月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
2月前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
下一篇
无影云桌面