前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring配置补充 (随笔详情扩展:)

Spring配置补充 (随笔详情扩展:)

作者头像
Java_慈祥
发布2024-08-06 13:11:11
1020
发布2024-08-06 13:11:11
举报
文章被收录于专栏:SSM专栏

Spring配置补充:

实现Spring 和 MyBatis 集成过程中学习了,Spring 的配置数据源的方法; 实际开发过程中还有很多灵活的配置文件;

灵活配置DataSource:

代码语言:javascript
复制
<!-- 远古方法(最初方法),数据库连接池,不过我最喜欢用的; -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/cart" ></property>
		<property name="username" value="root" ></property>
		<property name="password" value="ok" ></property>
	</bean> 

方式一 使用属性文件配置数据源; 还记得MyBatis可以引用外部的 .properties文件来配置数据源吗?Spring对于这些操作当然是小ks了; 首先,引入外部的文件,你前提得有哦! 假设为:datasource.properties

代码语言:javascript
复制
driver=com.mysql.jdbc.Driver
password=ok
#url=jdbc:mysql://localhost/cart
#user=root   
代码语言:javascript
复制
<!-- 方式一:使用属性文件配置数据源, -->
	<!-- 创建Bean class="xx..PropertyPlaceholderConfigurer" -->	
 	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
		<property name="location" value="classpath:datasource.properties"/>  <!-- 给属性赋值:引用外部文件-->	
	</bean>  
	<!-- 然后就是和之前的一样了,这样好处也就是可以把,数据源配置分开处理,便于维护,方便处理.. -->
  	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${driver}" />     	<!-- 通过${name} 来获取值;注意这里必须要完全和name一样,空格 啥的注意哦!-->
		<property name="url" value="jdbc:mysql://localhost:3306/cart" ></property>
		<property name="username" value="root" ></property>
		<property name="password" value="${password}" ></property>
	</bean>  

方式二 使用JNDI配置数据源; 了解JNDI 可以————— 点击.

代码语言:javascript
复制
<!-- 方式二:JNDI配置数据源
		配置JNDI的数据源(两种配置方式:)
			1.在tomcat安装目录下,打开conf文件夹,打开context.xml文件,在<context></context>标签之内插入代码:context.xml
			   好处:好处就是运行在配置过JNDI数据源的web容器下的项目都可以使用该数据源,也就是说在容器中配置好数据源之后,数据源在该web容器中是共享的。(多个项目可以使用!)
			2.将数据源配置在项目中,这样做的好处就是为每一个项目单独指定一个数据源,也就是说,数据源不会在服务器中共享。
			     配置方法:在项目路径下新建一个文件夹/src/main/webapp/META-INF/context.xml如果没有可自行创建。
 -->
 	<!-- Spring的配置文件: JndiObjectFactoryBean-->	
  	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">  
        <property name="jndiName">  
            <value>java:comp/env/jdbc/cart</value>  <!-- java:comp/env是固定写法,后面的jdbc/cart 是,配置文件中的 name="";-->
        </property>  
    </bean>   

服务器context.xml / 项目context.xml 中配置 数据源;

代码语言:javascript
复制
<Context>  
      <Resource name="jdbc/cart" auth="Container"   
      type="javax.sql.DataSource"  
      driverClassName="com.mysql.jdbc.Driver"  
      url="jdbc:mysql://localhost:3306/cart"  
      username="root"  						
      password="ok"  		
      maxActive="50"  
      maxIdle="30"  
      maxWait="10000" />  
</Context>
 <!-- 注意: 访问数据库/root/密码...,根据需求来,服务器的 服务器context.xml 已有<Context>节点就可以省了 -->

方式三 C3P0实现数据源配置

代码语言:javascript
复制
<!-- 方式三:C3P0实现数据源配置,Spring对C3P0有封装实现 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/cart"></property>
		<property name="user" value="root"></property>
		<property name="password" value="ok"></property>
		
		<!--依次为数据库连接池最小连接数、最大连接数、初始连接数-->
        <property name="minPoolSize" value="3"></property>
        <property name="maxPoolSize" value="15"></property>
        <property name="initialPoolSize" value="3"></property>
		
	</bean>

Spring中Bean的作用域:

Bean的作用域:

作用域

说明

singleton

默认值。Spring以单例模式创建Bean的实例,即容器中该Bean的实例只有一个

prototype

每次从容器中获取Bean时,都会创建一个新的实例, Spring不能对一个property bean的整个生命周期负责 因此客户端要负责property实例的生命周期管理

request

用于Web应用环境,针对每次HTTP请求都会创建一个实例

session

用于Web应用环境,同一个会话共享同一个实例,不同的会话使用不同的实例

global session

仅在Portlet的Web应用中使用,同一个全局会话共享一个实例。对于非Portlet环境,等同于session

实例: Spring配置文件:applicationContext.xml

代码语言:javascript
复制
	<!-- 默认, 		singleton-->
	<bean id="a类" class="类路径" ></bean>
	<!-- 指定作用域,	prototype -->
	<bean id="b类" class="类路径" scope="prototype"  ></bean>  
	<!-- scope:"设置作用域的值" -->
代码语言:javascript
复制
public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		A a1 = (A)context.getBean("a类"); //bean id;
		A a2 = (A)context.getBean("a类"); //bean id;
		System.out.println(a1==a2);  	  //结果为 true; 因为,Bean创建的默认级别以单例模式创建的,即该类对象在整个应用程序中,只有一个实例,多个对象指向是同一个空间地址;
		//单例模式的变量导致线程不安全;
		//一个程序只有一个 SqlSession 对象,当A线程执行新增 B修改,B完成了操作关闭了SqlSession 因为整个应用程序公用一个,导致A的也关闭了. A操作失败! 
	//解决:
		//可以通过改变, Spring中Bean的作用域: <bean id="……" class="……" scope="作用域"></bean>
		//B 类,Spring管理时设置了 scope 作用域;
		B b1 = (B)context.getBean("b类"); //bean id;
		B b2 = (B)context.getBean("b类"); //bean id;
		System.out.println(b1==b2);  	  //结果为 false; 
}

A B 类就随便创就好了!☺

使用注解指定Bean的作用域: 对于使用注解声明Bean 组件,如需修改其作用域,可以使用@Scope注解实现,关键字:

代码语言:javascript
复制
@Scope("prototype")		//指定作用域;		
@Component 				//声明Bean;
public class A {
}

Spring的自动装配:

之前章节介绍通过, @Autowired@Resource 注解实现依赖注解, 依靠着 Spring容器的自动装配功能; 通过自动装配技术, 可以将与属性类型相符的 (对于@Resource注解而言 还会尝试, ID 和属性名相符合) Bean自动注入给属性; 简化操作; autowire属性值及说明:

说明

no

默认值。Spring 默认不进行自动装配,必须显式指定依赖对象

byName

根据属性名自动装配。Spring 自动查找与属性名相同的id,如果找到,则自动注入,否则什么都不做

byType

根据属性的类型自动装配。Spring 自动查找与属性类型相同的Bean,如果刚好找到唯一的那个,则自动注入;如果找到多个与属性类型相同的Bean,则抛出异常;如果没找到,就什么也不做

constructor

和byType 类似,不过它针对构造方法。如果 Spring 找到一个Bean和构造方法的参数类型相匹配,则通过构造注入该依赖对象;如果找不到,将抛出异常

实例: Spring配置文件:applicationContext.xml

代码语言:javascript
复制
	<!-- 默认, 		singleton-->
	<bean id="a类" class="类路径"  autowire="byName"  > 		<!--根据属性名自动装配,查找 属性名与Bean id 匹配的自动装配 -->
		 <property name="属性名: B"  ref="B" ></property>   <!--向这种属性名 B 和要指定的Bean id一样的就可以省略不写了!-->
		....
	</bean>  
	<!-- autowire:"指定匹配方式"  -->

在Spring 配置文件中, 通过< bean > 元素, autowire 属性实现自动装配; < beans> 根目录:还提供了 default-autowire 属性, 设置该属性 影响全局, 减少单个 Bean的注入方式;

代码语言:javascript
复制
<?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"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"
		
		default-autowire="default"  
		> 
		<!-- 	default-autowire:设置全局操作;自动装配方式 -->
		<!-- 
			不过这种方式,对于大型应用,不鼓励使用自动装配,虽然可以减少工作量,但大大的降低了依赖关系,清晰性 透明性; 不能显而易见属性..类型..
			不利于高层次解耦合;
			
		-->
		
	</beans>

拆分Spring配置文件:

项目规模变大,配置文件可读性、可维护性差 团队开发时,多人修改同一配置文件,易发生冲突 更符合 “分而治之“ 的软件工程原理~ 两种方式 方式一: 当一个项目中有多个 Spring 配置文件:applicationContext1.xml applicationContext2.xml … 读取时:通过: ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext1.xml”,“applicationContext2.xml”); 方法的 重载来实现一次读取多个 配置文件; 或通过 (*) 通配符来指定多个; ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext *.xml”); // 文件的前缀. *来指定一定规范的命名文件; 除此之外还支持, String[] 形式传参数... 方式二: 设置一个配置文件为 : 配置文件的集成文件; 假设: 存在 A B 两个Spring 配置文件, 可以在 A 在引入B 文件/或更多…; 读取时候读取 A 就同时读取了 B …文件; A文件使用:来引入其它文件; < import resource=“B文件引用” />


配置web.xml

web.xml 都知道吧, 每一个 web项目都有一个 web.xml文件; 启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml 进行配置… Spring配置文件:

对于web项目: Spring配置文件需要在 web.xml 中进行配置, 以达到程序加载初始化读取Spring: 对Spring配置文件进行,初始化... 不在像以前控制台操作时通过: ApplicationContext context = new ClassPathXmlApplicationContext("Spring配置文件"); 加载Spring容器; 1.web.xml 中通过:contextConfigLocation参数指定,Spring配置文件的路径; 2.web 项目使用前: 启动对Spring容器加载; Spring提供一个监听器 org.springframework.web.context.ContextLoaderListener 该监听器实现了 : ServletContextListenter 接口, 可以在web 容器启动时候初始化 Spring容器;

web.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  
  <display-name>xxxxxx</display-name>		<!-- 描述的项目名 title -->

  <!-- 监听器: web项目使用前: 启动对Spring容器加载;  -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <context-param>
    <param-name>contextConfigLocation</param-name>							<!-- 指定Spring配置文件的位置路径 -->
    <param-value>classpath:applicationContext-mybatis.xml</param-value>		<!-- 指定Spring配置文件的位置路径 -->
  </context-param>
  
</web-app>

通过以上web.xml 配置, 就可以在启动同时初始化 Spring 容器了: 注意:

如果没有指定 contextConfigLocation 的参数, contextConfigLocation 会默认去查找: /WEB-INF/applicationContext.xml 换句话说就是: 如果我们将 SpringMVC的名字默认为: applicationContext.xml 并存储在 WEB-INF 路径下; 即使不指定 contextConfigLocation web.xml也会默认, 实现配置文件的加载~ 此外我们对于一些文件名较长的复杂的也可以同过 : applicationContetx-*.xml 通配符形式来实现装载文件;

小扩展classpath :

上述Demo及日常也经常看到 classpath 来配置文件路径… classpath 到底是啥呢? : classpath 表示是不是src 而是 WEB-INF/classes lib ( WEB-INF/ 是资源目录客户端不可以直接访问. ) 我们都知道一个传统的web项目结构: 如下↓↓↓

以前学Servlet 时做的笔记图在 oneNote上
以前学Servlet 时做的笔记图在 oneNote上

即使在src 中存储的 配置文件, 最后部署也会加载至项目 WEB-INF/calsses 文件中; 所以 classpath 表示的是 WEB-INF/calsses 目录; lib 和 classes 文件同属于 classpath , 两者的访问优先级为: lib>classes 即: 两个文件下存在相同文件名, classpath: 文件名.指定的是lib 下的;

ok。 又搞完一章, 智勇你看完了吗?
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring配置补充:
    • 灵活配置DataSource:
      • Spring中Bean的作用域:
        • Spring的自动装配:
          • 拆分Spring配置文件:
            • 配置web.xml
              • ok。 又搞完一章, 智勇你看完了吗?
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档