Spring学习总结_1

1 Spring 是什么?

  • Spring 是一个开源框架,Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson在其著作 Expert One-On-One J2EE Development and Design 中阐述的部分理念和原型衍生而来。
  • 它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE应用程序开发提供集成的框架。Spring 使用基本的 JavaBean 来完成以前只可能由 EJB 完成的事情。然而,Spring 的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。Spring 的核心是控制反转(IOC)和面向切面(AOP)。简单来说,Spring 是一个分层的 轻量级开源框架。

IOC : https://blog.csdn.net/ivan820819/article/details/79744797
软件设计六大原则 : http://www.uml.org.cn/sjms/201211023.asp#5
低耦合 : https://blog.csdn.net/ellis1970/article/details/84302912

2 为什么使用Spring

  • 1.方便解耦,简化开发
  • 2.Spring 就是一个大工厂,可以将所有对象创建和依赖关系维护,交给 Spring 管理
  • 3.AOP 编程的支持,Spring 提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
  • 4.声明式事务的支持只需要通过配置就可以完成对事务的管理,
  • 5.而无需手动编程方便程序的测试,Spring 对 Junit4 支持,可以通过注解方便的测试 Spring 程序
  • 6.方便集成各种优秀框架,Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持
  • 7.降低 JavaEE API 的使用难度,Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些 API 应用难度大大降低

3 Spring环境搭建

3.1 创建Spring项目,并引入相关依赖

在这里插入图片描述

3.1.1 项目创建

通过idea创建一个maven项目
在这里插入图片描述

3.1.2 引入spring的依赖

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.version>4.2.5.RELEASE</spring.version>
    </properties>   

			<!--Spring核心基础依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--日志相关-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--测试相关-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

3.2 添加配置文件

配置文件的名字可以任意设置,建议设置为applicationContext.xml,所以这里我们创建一个名为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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
 
</beans>

3.3 添加相应的模块

在项目中添加dao、model、service层代码

3.4 将bean的实例化交给Spring

<bean name="userDao" class="com.tledu.spring.dao.impl.UserDaoImpl" />
<!--name 属性名字/ref 引用的bean的名字-->
<bean id="userService" class="com.tledu.spring.service.UserService">
	<property name="userDao"  ref="userDao" />
</bean>

3.5 测试类

public class UserServiceTest {

    @Test
    public void add() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        // userService是bean的id或name
        UserService userService = (UserService) applicationContext
                .getBean("userService");
        userService.add(null);
    }
}

4 通过构造方法注入

上面的程序可以看出,是通过set方法注入的对象,那么如何通过构造方法注入呢?

 <bean name="userDao" class="com.tledu.spring.dao.impl.UserDaoImpl" />
    <bean id="userService" class="com.tledu.spring.service.UserService">
        <constructor-arg ref="userDao"/>
    </bean>

5 普通属性注入

上面我们注入的是关联对象,比如 int的值如何注入呢

	<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
	<!-- 如果不是指向对象,直接用value设置值就行 -->
		<property name="daoId" value="82"></property>
		<property name="daoStatus" value="good"></property>
	</bean>

6 scope

  • spring中scope是一个非常关键的概念,简单说就是对象在spring容器(IOC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式。
    目前,scope的取值有5种取值:
  • 在Spring 2.0之前,有singleton和prototype两种;
  • 在Spring 2.0之后,为支持web应用的ApplicationContext,增强另外三种:request,session和global session类型,它们只实用于web程序,通常是和XmlWebApplicationContext共同使用

6.1 singleton

  • 此取值时表明容器中创建时只存在一个实例,所有引用此bean都是单一实例。
  • 也就是说创建对象是单例模式,并且如果不进行设置,默认就行单例

6.2 prototype

  • spring容器在进行输出prototype的bean对象 时,会每次都重新生成一个新的对象给请求方,虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求 方之后,容器就不在拥有当前对象的引用,请求方需要自己负责当前对象后继生命周期的管理工作,包括该对象的销毁。也就是说,容器每次返回请求方该对象的一 个新的实例之后,就由这个对象“自生自灭”,最典型的体现就是spring与struts2进行整合时,要把action的scope改为 prototype。
  • 简单来说,就是每次获取都创建一个新对象,并且这个对象的生命周期不归Spring管理

6.3 request

  • request,session和global session类型只适用于web程序,通常是和XmlWebApplicationContext共同使用。
<bean id ="requestPrecessor" class="...RequestPrecessor"   scope="request" />
  • Spring容器,即XmlWebApplicationContext 会为每个HTTP请求创建一个全新的RequestPrecessor对象,当请求结束后,该对象的生命周期即告结束,如同java web中request的生命周期。当同时有100个HTTP请求进来的时候,容器会分别针对这10个请求创建10个全新的RequestPrecessor实例,且他们相互之间互不干扰,简单来讲,request可以看做prototype的一种特例,除了场景更加具体之外,语意上差不多。

6.4 session

  • 对于web应用来说,放到session中最普遍的就是用户的登录信息,对于这种放到session中的信息,我们可以使用如下形式的制定scope为session:
<bean id ="userPreferences" class="...UserPreferences"   scope="session" />
  • Spring容器会为每个独立的session创建属于自己的全新的UserPreferences实例,比request scope的bean会存活更长的时间,其他的方面没区别,如同java web中session的生命周期。

6.5 global session

<bean id ="userPreferences" class="...UserPreferences"   scope="globalsession" />

global session只有应用在基于porlet的web应用程序中才有意义,它映射到porlet的global范围的session,如果普通的servlet的web 应用中使用了这个scope,容器会把它作为普通的session的scope对待

6.6 配置scope方式

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
  <!-- 如果不是指向对象,直接用value设置值就行 -->
  <property name="daoId" value="82"></property>
  <property name="daoStatus" value="good"></property>
	</bean >
	<!-- scope singleton : 单例 只创建一个,默认就是 
		prototype : 每一次getBean 都会创建一个新的实例化对象  
  request,session : 需要特殊环境支持 -->
	<bean id="userService" class="com.tledu.zrz.service.UserService"
  scope="singleton">
  <!-- 构造方法注入 -->
  <constructor-arg>
  	<ref bean="userDao" />
  </constructor-arg>
</bean>

7 集合属性注入

7.1 相关类

UserDaoImpl中提供对应的变量

	private List<String> lists;
	private Set<String> sets;
	private Map<String, String> maps;
	public List<String> getLists() {
  		return lists;
	}
	public void setLists(List<String> lists) {
  		this.lists = lists;
	}
	public Set<String> getSets() {
 		 return sets;
	}
	public void setSets(Set<String> sets) {
 		 this.sets = sets;
	}
	public Map<String, String> getMaps() {
 		 return maps;
	}
	public void setMaps(Map<String, String> maps) {
 		 this.maps = maps;
	}

7.2 配置文件

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
  <property name="lists" >
  	<list>
    	<value>1</value>
    	<value>2</value>
  	</list>
  </property>
  <property name="sets" >
  <!-- set不可重复,重复不添加,所以只有第一个三 -->
  	<set>
    	<value>3</value>
    	<value>3</value>
    	<value>5</value>
    	<value>4</value>
  	</set>
  </property>
  <property name="maps">
  <!-- mapkey不可重复,重复key不添加,value覆盖 -->
  	<map>
    	<entry key="1"  value="2"></entry>
    	<entry key="1"  value="3"></entry>
    	<entry key="2"  value="2"></entry>
  	</map>
  </property>
	</bean>

	<bean id="userService" class="com.tledu.zrz.service.UserService"
  scope="singleton">
  <!-- 构造方法注入 -->
  <constructor-arg>
  	<ref bean="userDao" />
  </constructor-arg>
	</bean>

7.3 测试

8 自动装配

8.1 byName

上面我们进行对象注入的时候有两种方式
1 set方法注入

<property name="userDao" ref="userDao" />

2 构造方法注入

<constructor-arg>
    <ref bean="userDao"/>
</constructor-arg>

现在我们来学习自动注入,就是不需要指定以上两种方式

Autowire : 自动装配,两种取值
1 byName
2 byType

8.2 byType

  • byName是根据setter方法名字进行匹配,如果找不到,就不赋值
  • 如 setUserDao 方法 就会找userDao,如果 bean的ID为 UserDao 也一样找不到,区分大小写
  • 设置方式
<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
</bean>
<bean id="userService" class="com.tledu.zrz.service.UserService"  
 autowire="byName">
</bean>

8.3constructor

可以根据构造函数进行依赖的注入。

9 生命周期和迟加载

  • 之前servlet的生命周期
  • 构造方法 – init – service – destroy
    那么spring创建对象的生命周期呢?
  • Spring中是没有init、service和destroy的,但是我们可以指定某个方法在创建完对象之后执行,某个方法在最后销毁的时候执行.

9.1 生命周期

9.1.1 相关类

UserService中提供对应的方法

public void init(){
  System.out.println("init--------");
	}
	public void destroy(){
  System.out.println("destroy----------");
	}
	public UserService() {
  System.out.println("service构造方法");
}

9.1.2 配置文件

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
	</bean>
	<!--  
  init-method : 用于设置初始化的方法
  destory-method : 用于设置销毁资源的方法
  -->
	<bean id="userService" class="com.tledu.zrz.service.UserService"  
  autowire="byName"   init-method="init" destroy-method="destroy"  >
	</bean>

9.1.3 测试

@Test
public void testAdd() {
  ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
    "beans.xml");
  // userService是bean的id或name
   UserService userService = (UserService) applicationContext
   .getBean("userService");
  // // userService.add(null);
   System.out.println(userService.getUserDao());
  // 销毁Spring容器
   applicationContext.destroy();
}
  • Destroy之所以会执行,是因为我们默认创建对象的时候是单例模式
  • 这个时候对象的生命周期会和Spring容器的生命周期绑定到一起,所以当我们销毁Spring容器的时候,会把所有的对象销毁,并自动调用destroy方法
  • 但是如果我们把scope设置为prototype的时候,对象的生命周期就不会再和Spring容器绑定,销毁Spring容器的时候也就不会再执行该对象的destroy方法
  • 比如
<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
	</bean>
	<!--  
  init-method : 用于设置初始化的方法
  destory-method : 用于设置销毁资源的方法
  -->
	<bean id="userService" class="com.tledu.zrz.service.UserService"  scope="prototype"
  autowire="byName"   init-method="init" destroy-method="destroy"  >
</bean>

注意:scope为prototype类型时,我们容器只负责实例的创建,创建之后的生命周期由调用者负责。

9.2 迟加载

Spring容器默认是在执行

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

进行解析的时候创建对象并调用init,

  • 如果我们不想让某个类在解析的时候就创建对象,而是用到的时候在创建对象的话,就需要设置迟加载
  • 比如想要对userService迟加载可以这样设置

9.2.1 相关类

在UserDaoImpl和UserService中的构造方法添加输出语句进行测试

public UserDaoImpl(){
  System.out.println("Dao构造方法");
}
public UserService() {
  System.out.println("service构造方法");
}

9.2.2 配置文件

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
<bean id="userService" class="com.tledu.zrz.service.UserService"  scope="prototype"
  	autowire="byName"   init-method="init" destroy-method="destroy" lazy-init="true"  >
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Spring Boot、Spring Security和Spring Cloud的方法如下: 1. 官方文档:Spring官方提供了详细的文档和教程,包括入门指南、参考文档和示例代码。你可以从官方网站上找到相关文档并按照指南逐步学习。 2. 在线教程:有很多在线教程和视频教程可以帮助你学习Spring Boot、Spring Security和Spring Cloud。一些知名的在线教育平台(如慕课网、极客时间等)上有相关的课程,你可以选择适合自己的学习资源。 3. 实践项目:通过实际项目来学习是一种很有效的方法。你可以选择一个小型的项目,使用Spring Boot、Spring Security和Spring Cloud来构建。在实践中,你将学会如何应用这些框架,解决实际问题。 4. 社区论坛和博客:参与Spring社区的讨论和交流,可以通过问题和解答来加深对框架的理解。在Spring社区中,你可以找到一些活跃的论坛、博客和社交媒体账号,如Stack Overflow、CSDN、知乎等。 5. 开源项目:阅读和参与开源项目是学习的好方法。在GitHub等代码托管平台上,有很多与Spring Boot、Spring Security和Spring Cloud相关的优秀开源项目。你可以选择其中一个项目来研究源代码,学习最佳实践和设计模式。 总结来说,学习Spring Boot、Spring Security和Spring Cloud需要系统地学习官方文档,结合在线教程和实践项目进行深入理解,同时参与社区讨论和阅读开源项目的源代码。这样可以帮助你快速掌握这些框架并在实际开发中运用它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值