给软件行业带来了春天——揭秘Spring究竟是何方神圣(一)

2024-02-17 13:10

本文主要是介绍给软件行业带来了春天——揭秘Spring究竟是何方神圣(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

系列文章目录

给软件行业带来了春天——揭秘Spring究竟是何方神圣(一)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(二)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(三)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(四)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(五)


文章目录

  • 系列文章目录
    • 简介
    • Spring核心知识点
      • SpringIOC
        • 创建对象
          • 方法一:调用无参数构造器创建对象
          • 方法二:调用有参构造方法来创建对象
          • 方法三:使用静态工厂方法创建对象
          • 方法四:使用实例工厂方法来创建对象
          • 方法五:使用实例工厂创建对象
        • DI依赖注入
          • 基于对象属性set方法进行注入
          • 利用构造器方式进行注入
          • p名称空间注入
          • 集合类型属性注入
          • util标签注入
        • bean的常见属性
          • 作用域
          • 生命周期
          • 自动装配
        • SpringBean的注解形式


在这里插入图片描述

简介

    Spring是一个JavaEE开源的轻量级别的框架,可以解决我们企业开发中遇到的难题,能够让编码变的更加简单,核心组件IOC容器和Aop面向切面编程。

spring优点:

  • 方便解耦,简化开发
  • 管理对象
  • 集成其他框架
  • Junit单元测试
  • 方便进行事务操作
  • 降低API开发难度

spring框架图image.png

Spring 是模块化的。

Core 容器
Core 容器由 Core、Beans、Context 和 Expression Language 模块组成。

  • Core 模块提供了框架的基本部分,包括 IoC 和依赖注入功能。
  • Bean 模块提供了 BeanFactory,它是工厂模式的一个复杂的实现。
  • Context 模块建立在 Core 和 Beans 模块提供的坚实基础之上,它是访问任何已定义和配置的对象的媒介。 ApplicationContext 接口是上下文模块的焦点。
  • SpEL 模块提供了一种强大的表达式语言,用于在运行时查询和操作对象图。

数据访问/集成

数据访问/集成层由 JDBC、ORM、OXM、JMS 和 Transaction 事务模块组成。

  • JDBC 模块提供了一个 JDBC 抽象层,它消除了繁琐的 JDBC 相关编码的需要。
  • ORM 模块为流行的对象关系映射 API 提供集成层,包括 JPA、JDO、Hibernate 和 iBatis。
  • OXM 模块提供了一个抽象层,它支持 JAXB、Castor、XMLBeans、JiBX 和 XStream 的 Object/XML 映射实现。
  • Java 消息传递服务 JMS 模块包含用于生成和使用消息的功能。
  • Transaction 模块支持对实现特殊接口的类和所有 POJO 的编程和声明式事务管理。

Web

Web 层由 Web、Web-MVC、Web-Socket 和 Web-Portlet 模块组成。

  • Web 模块提供了基本的面向 Web 的集成功能,例如多部分文件上传功能以及使用 servlet 侦听器和面向 Web 的应用程序上下文初始化 IoC 容器。
  • Web-MVC 模块包含 Spring 的 Web 应用程序的 Model-View-Controller(模型-视图-控制器) (MVC) 实现。
  • Web-Socket 模块支持 Web 应用程序中客户端和服务器之间基于 WebSocket 的双向通信。
  • Web-Portlet 模块提供了在portlet 环境中使用的MVC 实现,并反映了Web-Servlet 模块的功能。

其他

如 AOP、Aspects、Instrumentation、Web 和 Test 模块。

  • AOP 模块提供了一个面向方面的编程实现,允许您定义方法拦截器和切入点,以清晰地解耦实现应该分离的功能的代码。
  • Aspects 模块提供与 AspectJ 的集成,AspectJ 又是一个强大且成熟的 AOP 框架。
  • Instrumentation 模块提供类检测支持和类加载器实现以用于某些应用程序服务器。
  • Messaging 模块支持将 STOMP 作为 WebSocket 子协议在应用程序中使用。 它还支持注解编程模型,用于路由和处理来自 WebSocket 客户端的 STOMP 消息。
  • Test 模块支持使用 JUnit 或 TestNG 框架对 Spring 组件进行测试。

Spring核心特性:

image.png

依赖注入 (DI):

Inversion of Control (IoC) 控制反转是一个通用概念,可以用多种不同的方式表达。 依赖注入只是控制反转的一个具体例子。在编写复杂的 Java 应用程序时,应用程序类应尽可能独立于其他 Java 类,以增加重用这些类的可能性,并在单元测试时独立于其他类对其进行测试。 依赖注入有助于将这些类粘合在一起,同时保持它们的独立性。
依赖注入简单来说,例如,依赖,A 类依赖于B类。注入就意味着,B 类将被 IoC 注入到 A 类中。


面向切面编程(AOP)

跨越应用程序多个点的功能称为横切关注点,这些横切关注点在概念上与应用程序的业务逻辑分开。 有各种常见的好例子,包括日志记录、声明式事务、安全性、缓存等。
OOP 中模块化的关键单元是类,而 AOP 中模块化的单元是方面。 DI 可帮助您将应用程序对象彼此分离,而 AOP 可帮助您将横切关注点与它们影响的对象分离。
面向切面是一种思想,不是具体的框架,也不是具体的代码。
更多消息可以去官方文档查看。

spring的官网:Home
Spring官方下载依赖jar包地址:JFrog
spring教程:Spring 教程

Spring核心知识点

SpringIOC

IOC(Inversion of Control) 控制反转是一种面对对象编程的设计原则,用于降低代码之间的耦合度。IOC容器主要作用就是创建对象和处理对象之间的依赖关系。
Bean的管理

  • 使用spring创建对象
  • 使用spring注入属性
创建对象
  1. 单独new方式—耦合度太高

每次单独new对象,没有实现统一管理对象,如果后期userDao的名称信息发生变化的情况下,需要改变的引用地方比较多,耦合度太高。

  1. 工厂模式—降低我们耦合度

概念:统一的管理和维护我们每个对象创建与使用的过程。
不需要自己new对象。

  1. 反射的方式

降低代码的-耦合度
反射创建对象

方法一:调用无参数构造器创建对象
  • 利用无参构造器
  • 给类添加一个无参构造器(缺省构造器)
  • 配置bean元素
  • 调用容器的getbean
public class  Fast {public Fast() {System.out.println("spring创建对象方式一:通过无参构造方法");}
}
<!--使用无参构造器创建对象id属性:bean的名称,要求唯一class属性:类的全名--><bean id="Fast" class="Fast"></bean>
@Test
public void test01(){ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
}

输出:image.png

方法二:调用有参构造方法来创建对象
public class Slow {private Integer id;private String name;public Slow(Integer id,String name){//super();this.id = id;this.name = name;System.out.println("spring创建对象方式2:通过有参构造方法"+"\n"+id+"-"+name);}}
<bean id="slow" class="Slow"><!--constructor-arg:是有参构造方法的使用标签index:参数的索引,从 0 开始name: 参数名type:参数类型(区分开关键字和封装类 int 和 Integer)此时的创建对象相当于:SomeBean2 bean=new SomeBean2(1,"alice");--><constructor-arg index="0" name="id" type="java.lang.Integer" value="1"/><constructor-arg index="1" name="name" type="java.lang.String" value="alice"/></bean>
@Test
public void test01(){ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
}

输出:image.png

方法三:使用静态工厂方法创建对象

通过调用类的静态工厂方法来创建对象

public class  Fast {public Fast() {System.out.println("spring创建对象第3种方式:通过静态方法工厂创建");}
}
public class FastFactory {public static Fast getInstance(){System.out.println("通过静态方法工厂创建对象");return new Fast();//相当于Fast.getInstance();}
}
 <!--使用静态工厂方法创建对象factory-method属性:指定一个静态方法,spring容器会调用这个静态方法来创建对象--><bean id="FastFactory"class="FastFactory"factory-method="getInstance"></bean>
@Test
public void test01(){ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
}

输出:image.png

方法四:使用实例工厂方法来创建对象

调用对象的实例方法来创建对象

public class cost {public cost(){System.out.println("通过实例工厂创建对象");}
}
public class costFactory {public cost getInstance(){return new cost();}}
 <!--通过实例工厂创建对象使用实例工厂方法来创建对象factory-bean属性:指定一个bean的ID,factory-method属性:指定一个方法spring容器会调用这个bean的对应的方法来创建对象。costFactory factory=new costFactory();cost cost=factory.getInstance();--><bean id="factory" class="costFactory"></bean><bean id="cost" factory-bean="factory" factory-method="getInstance"></bean>
@Test
public void test01(){ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
}

输出:image.png

方法五:使用实例工厂创建对象

public class messageBean {public messageBean(){System.out.println("通过实现FactoryBean接口实现对象的创建");}
}
public class bean implements FactoryBean<messageBean> {@Overridepublic messageBean getObject() throws Exception {return null;}@Overridepublic Class<?> getObjectType() {return null;}@Overridepublic boolean isSingleton() {return true;}
}
 <!--通过factorybean 来创建对象--><bean id="factotybean" class="bean"></bean>
@Testpublic void test01(){ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");messageBean bean=applicationContext.getBean("factotybean", messageBean.class);}

输出:image.png

DI依赖注入

spring容器通过调用对象提供的set方法或者构造器来建立依赖关系。
依赖关系的创建流程
spring 容器启动后读取配置文件

image.png
image.png

基于对象属性set方法进行注入

在Bean标签下 在定义一个属性<property>标签

  • property元素:表示使用set方法来注入依赖关系

属性值包含特殊符号
1 把<>进行转义 < >
2 把带特殊符号内容写到CDATA

   <!--<property name="bookName" value="<<武汉>>"></property> --><property name="bookName"><value><![CDATA[<<武汉>>]]></value></property>
  • name属性:指定属性值
  • ref属性:指定属性值(是被注入的bean的ID)
 <!--property元素:表示使用set方法来注入依赖关系name属性:指定属性值ref属性:指定属性值(是被注入的bean的ID)<!--null值--><property name="address"><null/></property><!--属性值包含特殊符号1 把<>进行转义 &lt; &gt;2 把带特殊符号内容写到CDATA --><property name="address"><value><![CDATA[<<上海>>]]></value></property>-->//注入属性 外部bean<bean id="dc1" class="ioc.dc"><bean id="db1" class="ioc.db"><property name="di" ref="dc1"></property></bean>
public class db {private IB di;private String name;public void setName(String name) {this.name = name;}public void setDi(IB di) {this.di = di;System.out.println("调用了方法");}
}
public class di implements IB{private String diname;public di(){}public void setDiname(String diname) {this.diname = diname;}public void f1(){System.out.println("注入bean的属性");}}
   /*test01测试set方式的注入* */@Testpublic void test01(){db db=abstractApplicationContext.getBean("db1",ioc.db.class);logger.info("依赖注入成功。");}

输出: image.png

注入属性—外部bean

//注入属性 外部bean<bean id="dc1" class="ioc.dc"><bean id="db1" class="ioc.db"><property name="di" ref="dc1"></property></bean>

注入属性—内部bean

//注入属性---内部bean
<property name="name" value="mysql"></property><property name="di" ><bean id="di2" class="ioc.di"><property name="diname" value="MYSQL AB"></property></bean></property></bean>

利用构造器方式进行注入

在Bean标签下 在定义一个属性**标签**
constructor-arg 元素:构造器方式注入
name 指定参数列表名称_,_** **index 指定参数列表索引,参数的下标(从0 开始)

public class A {private B b;public A(){System.out.println("A");}public A(B b){System.out.println("构造器方式注入");this.b=b;}public void execute(){System.out.println("成功注入");b.f1();}
}
public class B {public B(){System.out.println("对象被创建");}public void execute(){System.out.println("execute");}public void f1(){System.out.println("被成功注入");}}
<!--constructor-arg 元素:构造器方式注入,其中,index 属性指定参数的下标(从0 开始)--><bean id="b1" class="DI.B"></bean><bean id="a1" class="DI.A"><constructor-arg index="0" ref="b1"></constructor-arg></bean>
 /** 构造器注入* */@Testpublic void test01(){A a1=applicationContext.getBean("a1",A.class);a1.execute();logger.info("构造器方式注入完成");}

输出:image.png

p名称空间注入

Xml头部引入P标签:

<?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"xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd">
</bean>

使用p标签注入属性:

<bean id="Book" class="book" p:bookName="books" p:bookPrice="66">
</bean>

p名称注入也是调用了set 方法注入属性。

集合类型属性注入
  1. 注入数组类型
    2. 注入list集合类型
    3. 注入Map集合类型属性
    4. 注入set集合属性
public class stu {//四种类型属性private String[] courses;private List<String> list;private Map<String,String> map;private Set<String> set;//学生所学多门课程private List<course> courseList;public void setCourseList(List<course> courseList) {this.courseList = courseList;}public String[] getCourses() {return courses;}public void setCourses(String[] courses) {this.courses = courses;}public List<String> getList() {return list;}public void setList(List<String> list) {this.list = list;}public Map<String, String> getMap() {return map;}public void setMap(Map<String, String> map) {this.map = map;}public Set<String> getSet() {return set;}public void setSet(Set<String> set) {this.set = set;}
}
   <!--1 集合类型属性注入--><bean id="stu" class="bean_stu.stu"><!--数组类型属性注入--><property name="courses"><array><value>体育</value><value>数学</value></array></property><!--list类型属性注入--><property name="list"><list><value>张三</value><value>小三</value></list></property><!--map类型属性注入--><property name="map"><map><entry key="soccer" value="足球"></entry><entry key="basketball" value="篮球"></entry></map></property><!--set类型属性注入--><property name="set"><set><value>SQL</value><value>Java</value></set></property>
 @Testpublic void test01(){AbstractApplicationContext abstractApplicationContext=new ClassPathXmlApplicationContext("bean2.xml");stu stu=abstractApplicationContext.getBean("stu", bean_stu.stu.class);String str= JSONObject.toJSONString(stu);logger.info(str);}

输出image.png

集合里设置对象类型的值

<!--创建多个course对象--><bean id="course1" class="bean_stu.course"><property name="cname" value="PHP"></property></bean><bean id="course2" class="bean_stu.course"><property name="cname" value="C++"></property></bean><!--注入list集合类型,值是对象--><property name="courseList"><list><ref bean="course1"></ref><ref bean="course2"></ref></list></property></bean>

util标签注入

util :命名空间,用以区分。

  • 先引入一个util名称空间,将集合类型的值配置成一个bean,借用引用的方式注入集合,set等
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"><!--1 提取list集合类型属性注入--><util:list id="bookList"><value>A</value><value>B</value><value>C</value></util:list><!--2 提取list集合类型属性注入使用  单例和多例--><bean id="book" class="bean_stu.book" scope="prototype"><property name="list" ref="bookList"></property></bean>
</beans>
  • 使用util标签读取properties 文件的内容

classpath:按照类的路径来搜索
spring 容器会依据路径来找对对应的properties文件,然后读取该文件的内容到properties

 <util:properties id="config" location="classpath:config.properties"></util:properties>
  • 注入spring表达式
 <bean id="sp1" class="res.SpelBean"><property name="name" value="#{vb1.name}"></property><property name="age" value="#{vb1.age}"></property><property name="city" value="#{vb1.city[1]}"></property><property name="score"  value="#{vb1.score.english}"></property><property name="pageSize" value="#{vb1.pageSize}"></property></bean>

bean的常见属性

作用域
作用域描述
singleton在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
prototype每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。
session同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。
application限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。
<!--scope 属性: 用来配置作用域,缺省值为 singleton(即一个bean只能创建一个实例)如果值为prototype(即一个bean会创建多个实例)--><bean id="s2" class="cost" scope="prototype"></bean><bean id="s4"  class="cost"  scope="singleton"></bean><bean id="s5" class="cost" scope="session"></bean>
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>

生命周期

生命周期:初始化,分配资源 销毁 释放资源。

    <!--生命周期:初始化,分配资源 销毁 释放资源。init-method属性:指定初始化方法:destroy-method属性:指定销毁方法 不过如果作用域为单例时,销毁方法才执行。lazy-init属性:指定是否延迟加载,如果为TRUE,表示延迟加载,容器不会直接创建bean实例。--><bean id="messageBean1" class="init.messageBean" init-method="init" destroy-method="destroy" lazy-init="true"></bean><bean id="ExampleBean1" class="init.ExampleBean" init-method="init" destroy-method="destroy" lazy-init="true"></bean>

自动装配

自动装配指的是spring容器依据某种规则,自动建立对象之间的依赖关系
(默认情况下,容器不会自动装配。)可以通过指定autowire属性来告诉容器进行自动装配(容器实际上还是通过调用set方法或者构造器来完成依赖关系的建立。)

  • autowire属性: 自动装配,属性有三个值
  • byName :容器依据属性名来查找对对应的bean,然后调用对应的set方法来完成注入。如果找不到对应的bean,注入为null。不可能找到多个符合条件。
  • byType:容器依据属性类型来查找对应的bean,然后调用对应的set方法来完成注入。如果找不到对应的bean,注入null,有可能找到多个符合条件的bean,此时会 出错。
  • constructor: 与byType类似,不同的是调用对应的构造器的来完成注入。
<bean id="wt" class="res.Waiter"></bean>
<bean id="res1" class="res.Restaurant" autowire="byType">
</bean>

SpringBean的注解形式

注解:注解是JDK5中推出的新特性,代码的特殊标记。

  1. 基于XML方式实现
  2. 基于注解方式实现

注解可以使用在类、方法、属性上面。
使用注解的目的,简化xml的配置方式。
配置组件扫描
base-package属性:指定要扫描的包名,spring容器会扫描该包及其子包下面的所有的类,如果该类前面有特定的注解。
(比如@Component),则spring容器会将其纳入容器进行管理(相当于这儿配置了一个bean元素)

   通过注解来指定作用域<context:component-scan base-package="somebean"></context:component-scan>

自动扫描的注解标记
image.png
Spring提供的常用注解

  • @Component 将对象注入Spring容器中
  • @Service 注入业务逻辑对象
  • @Controller 控制器类
  • @Repository 注入dao对象

以上该四个注解底层都是基于@Component注解封装的,只是用于区分。
部分其他注解
@Autowired @Qualifier

  • 该注解支只持setter方式和构造器方式注解。当采用set方式注入时,可以将@Autowired添加到set方法前面,如果不使用@Qualifier,则容器会使用byType方式来注入,有可能出错。
  • 使用@Qualifier 明确要注入的对象类型id的bean的ID
  • 也可以直接将两个注解直接添加到属性前面,这样利用Java的反射机制,即使没有set方法,也可以。不过只会赋值,不会进行其他操作。
  • 当采用构造器注入时,可以将该注解添加到对应的构造器前面。
@Component("res")
public class res {/* @Autowired@Qualifier("wt3")*/private Waiter wt;public Waiter getWt() {return wt;}@Autowiredpublic void setWt(//注入进来的对象,类似于byName的属性。@Qualifier("wt3") Waiter wt) {this.wt = wt;System.out.println("测试:服务员");}public res(){System.out.println("res()");}
}

@Resource
只支持set方式注入
可以将该注解添加属性前,使用name属性指定要注入的bean的ID,(不指定会按照byType方式进行注入)
可以将该注解添加到属性前。

@Component("bar")
public class Bar {private Waiter wt;public Waiter getWt() {return wt;}@Resource(name = "wt3")public void setWt(Waiter wt) {this.wt = wt;}public Bar(){System.out.println("11");}}

@Value注解
可以使用该注解来注入基本类型的值
也可以使用该注解来使用spring表达式
该注解可以添加到属性前,或者添加到对应的set方法前。

@Value("#{config.pagesize}")private String pageSize;

@Configuration 注解
作为配置类,替代 xml 配置文件

@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages = { "bean"})
public class SpringConfig {
}

注解实例

@Component("b1")
@Scope("singleton")//单例和多例
@Lazy(true)//延迟加载
public class bean {@Value("#{config.pagesize}")private String pageSize;@Value("alice")private String name;@PostConstruct//初始化方法public void init(){System.out.println("初始化");}@PreDestroy//销毁方法public void destroy(){System.out.println("销毁");}public bean(){System.out.println("bean()");}@Bean(name="Bean")public bean getBean(){bean bean = new bean();System.out.println("调用方法:"+bean);return bean;}}

在本文中,我们揭开了 Spring 这个令软件行业为之动容的神秘面纱的一角。Spring 框架之所以如此备受推崇,不仅仅是因为它的灵活性和强大的功能,更因为它不断演进的能力,与软件发展的步伐同行。如果你对 Spring 框架的魅力产生了兴趣,那么请继续关注我们接下来的系列文章。在下一篇文章中,我们将深入探讨 Spring 的核心特性。

敬请期待!

在这里插入图片描述

这篇关于给软件行业带来了春天——揭秘Spring究竟是何方神圣(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/717855

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听