Spring学习笔记(基于配置文件)

简介

注释:Spring是Javaweb解决方案,是java最重要框架,没有之一

主要概念:

(1)IOC(控制反转):创建bean权利交给第三方IOC容器负责

(2)DI(依赖注入):Bean与Bean之间的注入关系交给第三方

(3)AOP(面向切面编程):横向功能抽取,增强Bean

1 文件配置

1.1 web.xml

注释:在web.xml中通过上下文监听器,配置Spring的核心配置文件

XML 复制代码
	<context-param>
	  <param-name>contextConfigLocation</param-name>
	  <param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	<listener>
	  <listener-class>
	    org.springframework.web.context.ContextLoaderListener
	  </listener-class>
	</listener>

1.2 applicationContext.xml

maven工程在 resources下新建 applicationContext.xml

旧版WebContent工程在 WEB-INF根目录下新建 applicationContext.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
	   http://www.springframework.org/schema/beans/spring-beans.xsd">
	   
 </beans>

1.3 包扫描

配置文件:<context:component-scan base-package="包.包"/>

注释:将指定包下有注解@Service, @Repository 等的bean交给容器管理

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       ...>

   <context:component-scan base-package="com.example.service" />
</beans>

2 IOC容器

2.1 容器获取

(1) 根据系统配置文件取容器

ApplicationContextctx = new ClassPathXmlApplicationContext("applicationContext.xml");

(2) 根据本地配置文件取容器

ApplicationContextctx = new FileSystemApplicationContext("D:\\xx\applicationContext.xml");

注释:两种方式都可以逗号分隔获取多个配置文件

2.2 通过容器获取Bean

(1) 类 xx = (类) ctx.getBean("bean名称或id");

(2) 类 xx = ctx.getBean("bean名称或id", 类.class);

(3) 类 xx = ctx.getBean(类.calss); // 容器中只能有一个该类型

(4) 旧版 BeanFactory b=new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

b.getBean(...);

注释:BeanFactory默认延迟加载,获取容器时不调用bean的构造方法。

注释:ApplicationContext默认立即加载,获取容器是调用bean的构造方法。可通过<bean lazy-init="true" />开启延迟加载

2.3 关闭容器

(1) classPathXmlApplication.close() // 直接关闭容器

(2) ctx.tegisterShutdownHook() // 关闭虚拟机前关闭容器

java 复制代码
public void handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception {
    String webRoot = req.getServletContext().getRealPath("/"); // 获取 Web 根目录
    FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(webRoot + "WEB-INF/applicationContext.xml");
    LoginService service = (LoginService)ctx.getBean("loginService");
    ctx.close();
}

3 Bean

3.1 bean基本属性

(1) id: // 唯一标识,依赖注入的ref和getBean都可指定名称获取。

(2) class: // bean的全类名或接口名

(3) name: // 别名[逗号分号空格] 可分割多个,依赖注入的ref和getBean都可指定名称获取。

XML 复制代码
<bean id="bean2" 
    name="bean_name2 bean_name3" 
    class="com.test.dao.Dao01BeanConfigTest" />

(4) scope:scope="prototype多例,singleton默认单例"

注释:适合单例的对象controller,service,dao。多例对象entity

(5) autowire:autowire="byType" //按类型自动装配, byName按名称

(6) lazy-init:lazy-init="true" //开启延迟加载,默认立即加载

其它:init-method,destroy-method, factroy-method, factory-bean

3.2 bean的实例化

(1) 构造器实例化

applicationContext:配置bean

XML 复制代码
<bean id="bean1" class="com.test.service.Service01BeanConfigTest" />

对象类:公开无参构造器

java 复制代码
public class Service01BeanConfigTest {
	public void test() {
		System.out.println("service...");
	}
}

(2) 静态工厂(旧)

applicationContext:<bean id="xx" class="xx" factory-method="工厂类静态方法" />

XML 复制代码
	   <bean id="bean3" 
	   		class="com.test.service.factory.ServiceBeanFactory" 
	   		factory-method="createServiceBean" />

工厂类:公开静态方法,返回对象实例

java 复制代码
public class ServiceBeanFactory {
	public static Service01BeanConfigTest createServiceBean() {
		return new Service01BeanConfigTest();
	}
}

(3) 实例工厂

applicationContext:<bean id="xx" class="实例工厂全类名" />

<bean id="xxx" factory-method="工厂类方法名" factory-bean="工厂类beanid" />

XML 复制代码
  	   <bean id="bean4" class="com.test.dao.factory.DaoBeanFactory" />
  	   <bean id="bean5" factory-method="createDaoBean" factory-bean="bean4" />

工厂类:公开方法,返回对象实例

java 复制代码
public class DaoBeanFactory {
	public Dao01BeanConfigTest createDaoBean() {
		return new Dao01BeanConfigTest();
	}
}

(4) 泛型工厂类

applicationContext:<bean id="xx" class="泛型工厂全类名" />

XML 复制代码
<bean id="bean6" class="com.test.model.factory.ModelBeanFactory" />

工厂类:实现FactoryBean<类>接口

java 复制代码
public class ModelBeanFactory implements FactoryBean<Model1>{
	@Override
	public Model1 getObject() throws Exception {
		return new Model1();
	}
	@Override
	public Class<?> getObjectType() {
		return Model1.class;
	}
	@Override
	public boolean isSingleton() {
		// true单例,false多例
		return false;
	}
}

3.3 bean的生命周期

(1) 方式1(配置)

bean类:创建公开无参,init, destroy方法

XML 复制代码
<bean id="bean7" 
    class="com.test.model.Model1" 
    init-method="init" 
    destroy-method="destroy" />

applicationContext:<bean id="xx" class="xx" init-method="init" destroy-method="destroy" />

注释:bean初始化执行init方法,销毁执行destroy方法

(2) 方式2(接口)

bean类:实现InitializingBean, DisposableBean接口

bean类:实现destroy,afterPropertiesSet方法(先执行set方法再执行初期化)

注释:无需配置文件

java 复制代码
public class Model2 implements InitializingBean, DisposableBean{
	@Override
	public void destroy() throws Exception {
		System.out.println("model2 销毁了");
	}
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("model2 初始化了");
	}
}

4 DI依赖注入

4.1 字面量注入

(1) set函数注入

applicationContext:<property name="类属性名" value="值" />

XML 复制代码
  	   <bean id="bean13" class="com.test.model.Model03BeanDiSetTest">
  	   		<property name="name" value="zhangsan"/>
  	   </bean>

Bean对象:定义私有变量,公开无返回值set函数

java 复制代码
public class Model03BeanDiSetTest {
	private String name;
	public void setName(String name) {
		this.name=name;
	}
	public void test() {
		System.out.println("名称:"+name);
	}
}

(2) 构造器注入

applicationContext按名称:<constructor-arg name="构造器参数名" value="值"/>

注释:多个参数可定义多个constructor-arg ,按名称匹配与构造器参数顺序无关

XML 复制代码
   	   <bean id="bean14" class="com.test.model.Model04BeanDiConstructorTest">
  	   		<constructor-arg name="name" value="zs"/>
            <constructor-arg name="age"  value="18"/>
  	   </bean>

applicationContext按类型:<constructor-arg type="java.long.String" value="值"/>

XML 复制代码
   	   <bean id="bean15" class="com.test.model.Model04BeanDiConstructorTest">
  	   		<constructor-arg type="String" value="zs"/>
  	   		<constructor-arg type="int"    value="18"/>
  	   </bean>

applicationContext按下标:<constructor-arg index="0" value="值"/>

XML 复制代码
   	   <bean id="bean15" class="com.test.model.Model04BeanDiConstructorTest">
  	   		<constructor-arg index="0" value="zs"/>
  	   		<constructor-arg index="1" value="18"/>
  	   </bean>

Bean对象:定义公开构造器

java 复制代码
public class Model04BeanDiConstructorTest {
	private String name;
	private int age;
	public Model04BeanDiConstructorTest(String name, int age) {
		this.name=name;
		this.age=age;
	}
}

4.2 对象注入

注释:set为可选注入,配置文件不指定property,属性可以是空对象。构造器注入必须指定对象。

(1) set函数注入

applicationContext:<property name="类属性名" ref="注入bean的id" />

注释:多个参数可定义多个property

XML 复制代码
  	   <bean id="bean9" class="com.test.dao.Dao02BeanDiTest"/>
  	   <bean id="bean10" class="com.test.service.Service02BeanDiTest">
  	   		<property name="dao" ref="bean9"/>
            <!-- 可以指定多个<property name="dao" ref="bean9"/>-->
  	   </bean>

Bean对象:定义私有变量,公开无返回值set函数

java 复制代码
public class Service02BeanDiTest {

	private Dao02BeanDiTest dao;
	public void setDao(Dao02BeanDiTest dao) {
		this.dao = dao;
	}
	
	public void test() {
		System.out.println("service 执行了");
		dao.test();
	}
}

(2) 构造器注入

applicationContext:<constructor-arg name="构造器参数名" ref="注入bean的id"/>

注释:多个参数可定义多个constructor-arg ,按名称匹配与构造器参数顺序无关

XML 复制代码
	   <bean id="bean11" class="com.test.dao.Dao03BeanDiConstructorTest"/>
  	   <bean id="bean12" class="com.test.service.Service03BeanDiConstructorTest">
  	   		<constructor-arg name="dao" ref="bean11"/>
  	   </bean>

Bean对象:定义公开构造器

java 复制代码
public class Service03BeanDiConstructorTest {

	private Dao03BeanDiConstructorTest dao;
	public Service03BeanDiConstructorTest(Dao03BeanDiConstructorTest dao) {
		this.dao = dao;
	}
	
	public void test() {
		System.out.println("service03 执行了");
		dao.test();
	}
}

4.3 集合注入

(1) 数组

applicationContext:<property name="类属性名"> <array>...

XML 复制代码
   	   <bean id="bean16" class="com.test.model.Model05BeanDiArrayTest">
  	   		<property name="test1">
  	   			<array>
  	   				<value>zhangsan</value>
  	   				<value>lisi</value>
  	   			</array>
  	   		</property>
  	   </bean>
java 复制代码
public class Model05BeanDiArrayTest {

	private String[] test1;
	public void setTest1(String[] test1) {
		this.test1 = test1;
	}
	
	public void test() {
		for (String str : test1) {
			System.out.println("集合1:"+str);
		}

	}
}

(2) List

applicationContext:<property name="类属性名"> <list>...

XML 复制代码
  	   		<property name="test2">
  	   			<list>
  	   				<value>zhangsan</value>
  	   				<value>zhangsan</value>
  	   			</list>
  	   		</property>
java 复制代码
	private List<String> test2;
	public void setTest2(List<String> test2) {
		this.test2 = test2;
	}

(3) Set

注释:集合会对内容去重

applicationContext:<property name="类属性名"> <set>...

XML 复制代码
  	   		<property name="test3">
  	   			<set>
  	   				<value>zhangsan</value>
  	   				<value>zhangsan</value>
  	   			</set>
  	   		</property>
java 复制代码
	private Set<String> test3;
	public void setTest3(Set<String> test3) {
		this.test3 = test3;
	}

(4) Map

applicationContext:<property name="类属性名"> <map>...

XML 复制代码
  	   		<property name="test4">
  	   			<map>
  	   				<entry key="key1" value="value1" />
  	   				<entry key="key2" value="value2" />
  	   			</map>
  	   		</property>
java 复制代码
	private Map<String, String> test4;
	public void setTest4(Map<String, String> test4) {
		this.test4 = test4;
	}

(5) Properties

applicationContext:<property name="类属性名"> <props>...

XML 复制代码
  	   		<property name="test5">
  	   			<props>
  	   				<prop key="prop1">val1</prop>
  	   				<prop key="prop2">val2</prop>
  	   			</props>
  	   		</property>
java 复制代码
	private Properties test5;
	public void setTest5(Properties test5) {
		this.test5 = test5;
	}

5 自动装配

注释:不能自动装配基本类型 ,自动装配优先级低于,构造器与setter注入。

5.1 按类型

(1) Bean:定义私有引用变量,定义set方法

(2) 配置:<bean id="xx" class="xx" autowire="byType"></bean>

注释:需在配置文件中有对应类型的Bean

java 复制代码
public class Service04BeanAutowire {

	private Dao04BeanAutowire dao;
	public void setDao(Dao04BeanAutowire dao) {
		this.dao = dao;
	}
	
	public void test() {
		System.out.println("service04 执行了");
		dao.test();
	}
}
XML 复制代码
   	   <bean id="bean17" class="com.test.dao.Dao04BeanAutowire"></bean>
   	   <bean id="bean18" class="com.test.service.Service04BeanAutowire" autowire="byType"></bean>

5.2 按名称

(1) Bean:定义私有引用变量,定义set方法

(2) 配置:<bean id="xx" class="xx" autowire="byName"></bean>

注释:同类型有多个bean时,类变量名要与配置的注入bean的唯一id相同

java 复制代码
public class Service05BeanAutowireName {
	private Dao04BeanAutowire bean19;
	public void setBean19(Dao04BeanAutowire bean19) {
		this.bean19 = bean19;
	}
	
	public void test() {
		System.out.println("service05 执行了");
		bean19.test();
	}
}
XML 复制代码
   	   <bean id="bean17" class="com.test.dao.Dao04BeanAutowire"></bean>
   	   <bean id="bean19" class="com.test.dao.Dao04BeanAutowire"></bean>
	   <bean id="bean20" class="com.test.service.Service05BeanAutowireName" autowire="byName"></bean>

6 第三方Bean

<bean id="xxx" class="第三方包.类">

<property name="三方bean属性" ref="引用类型bean注入"/>

<property name="三方bean属性" value="基本类型注入" />

</bean>

XML 复制代码
   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
       <property name="driverClassName" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>
   </bean>

7 AOP面向切面编程

注释:不动原代码,添加功能。目标方法(连接点),配置方法(切入点)。

7.1 配置命名空间

XML 复制代码
<beans xmlns="...
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xsi:schemaLocation="
	   ...
   	   http://www.springframework.org/schema/aop
   	   http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
   	   ">

7.2 详细配置

8 数据源与事务控制

8.1 数据源配置

(1) 新建 jdbc.properties

注释:jdbc还可以有其他配置,maxTotal=30,lnaxIdle=10,initialSize=5等等。。

(2) 加载properties

applicationContext:加入引文件需要的配置

XML 复制代码
<?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:context="http://www.springframework.org/schema/context"
	   xsi:schemaLocation="
	   http://www.springframework.org/schema/beans
	   http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
   	   http://www.springframework.org/schema/context/spring-context.xsd">

加载properties:<context:property-placeholder location="classpath:jdbc.properties"/>

可选属性:system-properties-mode="never" 不加载系统username等属性

批量加载:方式1:location="x1.properties,x2.properties"

批量加载:方式2:location="classpath:*.properties" // 只能加载当前工程文件

批量加载:方式2:location="classpath*:*.properties" // 可以加载jar包内部文件

XML 复制代码
   <context:property-placeholder location="classpath:jdbc.properties"/>

加载属性使用:xx="${jdbc.driver}" //读取配置文件内容

XML 复制代码
   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
       <property name="driverClassName" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>
   </bean>

8.2 管理数据源

注释:用数据库需引jar包 mysql-connector-j-8.0.32.jar

(1) dbcp:driverClassName, url, username, password

(2) druid:driverClassName, url, username, password// 阿里提供,集优点于一身

(3) c3p0:driverClass, jdbcUrl, user, password// 速度稍慢相对稳定

注释:BoneCP (比C3P0/DBCP连接池速度快25倍?)

XML 复制代码
		<bean id="dataSource1" class="org.apache.commons.dbcp2.BasicDataSource">
			<property name="driverClassName" value="${jdbc.driver}" />
			<property name="url" value="${jdbc.url}"/>
			<property name="username" value="${jdbc.username}"/>
			<property name="password" value="${jdbc.password}"/>
		</bean>
		<bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource">
			<property name="driverClassName" value="${jdbc.driver}" />
			<property name="url" value="${jdbc.url}"/>
			<property name="username" value="${jdbc.username}"/>
			<property name="password" value="${jdbc.password}"/>
		</bean>
		<bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource">
			<property name="driverClass" value="${jdbc.driver}" />
			<property name="jdbcUrl" value="${jdbc.url}"/>
			<property name="user" value="${jdbc.username}"/>
			<property name="password" value="${jdbc.password}"/>
		</bean>

8.3 事务控制

需要:spring-tx.jar(PlatformTransactionManager接口)事务管理包,spring-jdbc.jar(DataSourceTransactionManager实现类),

(1) 配置文件事务

applicationContext.xml配置

<bean transactionManager://事务管理器

<tx:annotation-driven: 注册事务驱动,开启事务注解

XML 复制代码
<beans xmlns="...
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xsi:schemaLocation="
	   ...
   	   http://www.springframework.org/schema/tx
   	   http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
   	   ">
		<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
			<property name="driverClassName" value="${jdbc.driver}" />
			<property name="url" value="${jdbc.url}"/>
			<property name="username" value="${jdbc.username}"/>
			<property name="password" value="${jdbc.password}"/>
		</bean>
	    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">									
			<property name="dataSource" ref="dataSource"/>								
		</bean>										
				
		<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

9 整合框架

(1) mybatis-config.xml:

XML 复制代码
<configuration>		
	<typeAliases>	
		<package name="com.ssm.pojo"/>  设置对象别名
	</typeALiases>	
</configuration>		

(2) applicationContext.xml

XML 复制代码
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
//配置mybatais工程	
	<property name="dataSource" ref="dataSource" />  数据源
	<property name="configLocation" value="classpath:mybatis-config.xml"/>  核心文件
</bean>	
	
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer".	
	<property name="basePackage" ref="com.ssm.dao" />  // 配置mapper扫描
</bean>	
<context:component-scan base-package="com.ssm.service" /> service扫描	

(3) Service实现:

java 复制代码
@Service
@Transactional  //方法纳入spring事务管理
public class XxService {
    @AutoWired
    private UserDao userDao;
}
相关推荐
bobasyu2 小时前
Claude Code 源码笔记 -- queryLoop
java·笔记·spring
计算机学姐2 小时前
基于SpringBoot的高校竞赛管理系统
java·spring boot·后端·spring·信息可视化·tomcat·mybatis
砍材农夫2 小时前
spring-ai 第七模型介绍-向量模型
java·人工智能·spring
我叫张土豆3 小时前
Spring AI 集成 MCP 服务踩坑实录:SSE 与 Streamable HTTP 协议的兼容性深度剖析
人工智能·spring·http
rrrjqy4 小时前
深入浅出 RAG:基于 Spring AI 的文档分块 (Chunking) 策略详解与实战
java·人工智能·后端·spring
二进制person4 小时前
JavaEE进阶 --Spring Framework、Spring Boot和Spring Web MVC(3)
spring boot·spring·java-ee
我是大猴子4 小时前
Spring源码的解析
java·mysql·spring
bKYP953cL5 小时前
Prompt 缓存的四种策略:从精确匹配到语义检索
spring·缓存·prompt
云烟成雨TD1 天前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring