学习Spring

Posted 月下赶路人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Spring相关的知识,希望对你有一定的参考价值。

文章目录

Spring

​ 传统的Java EE在解决企业级应用时会出现诸如开发效率低、开发难度大、实际性能能差等问题。Spring致力于Java EE应用的各种解决方案,不仅仅专注于某一层的方案。Spring可以说是企业级应用开发的“一站式”选择。Spring贯穿表现层、业务层、持久层,并且可以和其它已有的框架无缝整合。传统的Java EE开发企业级应用时存在代码层层之间耦合性过高,后期扩展性低等问题。Spring则解决了业务层与其它各层之间的耦合,其特性表现为高内聚、低耦合。

​ Spring即Spring Framework。是一个开源的、轻量级的企业应用开发框架,能够创建出松耦合、易测试、易维护的Java应用系统。坚持“绝不做重复轮子”的原则,对于已有较好解决方案的领域,Spring绝不做重复性的实现。例如对象持久化和ORM,Spring只对现有JDBC、MyBatis等技术提供支持,使之更加易用,而不是重新做一个实现。框架的主要优势之一就是分层架构,允许自行选择使用哪一个组件。

Spring的核心及优点

Spring的核心

​ Spring的核心是控制反转(IOC)和面向切面编程(AOP)。Spring根据代码的功能特点,使用IOC降低业务之间的耦合度。IOC使得主业务在相互调用的过程中,不用自己创建要使用的对象,而是由Spring容器统一管理,自动“注入”(赋值)。而AOP使系统服务得到最大复用,不用我们手工将系统级服务“混杂”到主业务逻辑中了,而是由Spring容器完成“织入”。

Spring的优点

  1. 轻量级

    ​ Spring框架运行占用的资源校,运行效率高。Spring框架使用的jar都比较小,一般都在1M以下或几百kb,核心功能的所需jar总共再3M左右,但这种说法其实是仁者见仁智者见智,虽然核心功能的jar包小,但当我们在完整的使用Spring框架做项目时,我们所要集成的各种jar包也是相当庞大的。

  2. 非侵入式

    ​ 编写一些业务类时不需要继承Spring特定的类,通过配置完成依赖注入后就可以使用,此时,Spring就没有侵入到我们的业务类代码中。

  3. 针对接口编程——解耦合

    ​ 这里的耦合是指两个或两个以上的对象通过相互引用而彼此影响甚至结合的现象。Spring提供了IOC控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成,促进了低耦合,即对象之间解耦合。

  4. AOP编程的支持

    ​ AOP(面向切面编程),许多不容易用传统OOP(面向对象编程)实现的功能都可以通过AOP轻松应付在Spring中开发人员可以从繁杂的事务管理代码中解脱出来,通过声明的方式灵活进行事务的管理,提高开发效率和质量。

5.一站式框架

​ Spring本身也提供了数据访问功能和web功能,以及可以很好的管理其它框架。

Spring环境搭建

  1. 创建maven项目。
  2. pom.xml中添加依赖:
<!-- 进行Junit单元测试 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>provided</scope>
</dependency>

<!--依赖log4j的日志管理-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

<!--提供了框架的基本组成部分,包括IOC和DI-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.1.6.RELEASE</version>
</dependency>

<!--提供了BeanFactory-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.1.6.RELEASE</version>
</dependency>

<!--上下文配置对象,提供一个框架式的对象访问方式-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.6.RELEASE</version>
</dependency>


<!--提供了强大的表达式语言-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>4.1.6.RELEASE</version>
</dependency>
  1. 在resources下创建Spring的配置文件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>

注意: Schema和DTD的区别和联系

​ (1)联系:都是XML文件的验证器。

​ (2)Schema是DTD的升级版,可扩展性强。在一个xml文件中引入多个xsd文件,xmlns:自定义名称=“路径”;在一个xml文件中只能引入一个dtd文件。

  1. 创建实体类以及将实体类交给sprig管理实现IOC
public class User 
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    
    //get set 构造 tostring

<?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">

    <bean id="user1" class="com.cwd.bean.User">

    </bean>

</beans>
  1. 测试
@Test
public void test1() 
    //1.加载配置文件
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");

    //2.获得User对象
    User user = (User) app.getBean("user1");
    user.setId(001);
    user.setName("张三");
    user.setAge(18);
    user.setSex("男");

    System.out.println(user);

Spring IOC

  1. IOC实现的好处:实现了代码间的解耦。

  2. 控制反转:

    (1)控制:创建对象的过程。

    (2)反转:创建对象的操作本身是程序员自己完成的,现在是反转给Spring进行创建。

Spring IOC创建对象的方式

  1. 使用无参构造
public class User 
    private Integer id;
    private String name;
    private Integer age;
    private String sex;

    public User() 

    

<!--
        id:唯一标识
        class:当前创建对象的全局限定名
-->
<bean id="user1" class="com.cwd.bean.User">

</bean>
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) app.getBean("user1");//这就是使用无参构造
  1. 使用有参构造
public class User 
    private Integer id;
    private String name;
    private Integer age;
    private String sex;

    public User(Integer id, String name, Integer age, String sex) 
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
    

<!--使用有参构造创建对象-->
<bean id="user2" class="com.cwd.bean.User">
    <!--
        name值:构造方法中参数名相同;
        index值:构造方法中参数的位置,从0开始;
        value值:一般为简单类型赋值;
        ref:一般为引用类型赋值;
        type:值类型
    -->
    <constructor-arg name="id" value="003"/>
    <constructor-arg name="name" value="王五"/>
    <constructor-arg name="age" value="20"/>
    <constructor-arg name="sex" value=""/>
</bean>
@Test
public void test2() 
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = (User) app.getBean("user2");
    System.out.println(user);

  1. 使用工厂模式

    工厂模式属于设计模式的一种,使用工厂设计模式可以达到对象的统一管理,可以批量的产生某一类对象。

    实现方式

    (1)使用实例工厂类+无参

    //创建一个实例工厂
    public class UsersFactory 
        public User getInstance() 
            return new User(001,"张三",21,"女");
        
    
    
    <!--
        使用工厂模式创建对象
        1.创建工厂对象
        2.根据工厂对象,创建user对象,factory-bean是工厂对象,factory-method是工厂对象方法
    -->
    <bean id="userFactory" class="com.cwd.factory.UsersFactory"/>
    <bean id="user3" factory-bean="userFactory" factory-method="getInstance"/>
    

    (2)使用静态工厂类+无参

    public class UsersFactory 
        public static User getInstance() 
            return new User(004,"李四",31,"女");
        
    
    
    <!--
        使用静态工厂模式+无参
        直接指定哪个工厂的哪个方法生成对应的bean对象
    -->
    <bean id="user4" class="com.cwd.factory.UsersFactory" factory-method="getInstance"/>
    

    (3)使用实例工厂类+有参

    public class UsersFactory 
        public User getInstance(User user) 
            return user;
        
    
    
    <!--使用实例工厂类+有参-->
    <bean id="userFactory" class="com.cwd.factory.UsersFactory"/>
    <bean id="user5" factory-bean="userFactory" factory-method="getInstance">
        <constructor-arg name="user" ref="user1"/>
    </bean>
    

    (4)使用静态工厂类+有参

    public class UsersFactory 
        public static User getInstance(User user) 
            return user;
        
    
    
    <!--
        使用静态工厂类+有参
    -->
    <bean id="user6" class="com.cwd.factory.UsersFactory" factory-method="getInstance">
        <constructor-arg name="user" ref="user2"/>
    </bean>
    

Spring DI注入

DI:全称Dependency Injection,依赖注入。

利用DI进行解决

  1. 为什么使用DI(依赖注入)?

    作用:给对象中的全局属性进行赋值的操作。

  2. 依赖注入是什么?

    依赖:一个类在另一个类中作为全局属性时称作依赖。

    注入:通过Spring容器为自己的属性注入一个值。

  3. DI的意义?

    可以解除类与类之间的耦合度,并为对象中的全局对象进行赋值。

  4. 如何理解DI和IOC。

    Spring帮助创建对象的过程就叫做IOC,创建对象时给对象的全局对象赋值的操作叫做DI。

DI注入的方式

准备两个类:

public class User 
    private Integer id;
    private String name;
    private Integer age;
    private String sex;

    public User() 

    

    public User(Integer id, String name, Integer age, String sex) 
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
    
  
  	//get,set,toString()方法


public class Student 
    private Integer stuid;
    private String stuname;
    private Integer stuage;
    private User user;

    public Student() 

    

    public Student(Integer stuid, String stuname, Integer stuage, User user) 
        this.stuid = stuid;
        this.stuname = stuname;
        this.stuage = stuage;
        this.user = user;
    
  
  	//get,set,toString()方法

构造完成注入
<!--
    使用有参构造完成DI操作
    1.创建User对象;
    2.创建Student对象
-->
<bean id="user" class="com.cwd.bean.User">
    <constructor-arg name="id" value="003"/>
    <constructor-arg name="name" value="王五"/>
    <constructor-arg name="age" value="20"/>
    <constructor-arg name="sex" value=""/>
</bean>


<bean id="student" class="com.cwd.bean.Student">
    <constructor-arg name="stuid" value="001"/>
    <constructor-arg name="stuname" value="天天"/>
    <constructor-arg name="stuage" value="15"/>
    <constructor-arg name="user" ref="user"/>
</bean>
属性注入
<!--
    使用属性注入方式,要求属性有set方法
-->
<bean id="student1" class="com.cwd.bean.Student">
    <property name="stuid" value="002"/>
    <property name="stuname" value="晶晶"/>
    <property name="stuage" value="17"/>
    <property name="user" ref="user"/>
</bean>

不同数据类型的注入方式

(1)String或基本类型

<property name="stuname" value="晶晶"/>

(2)对象类型

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

(3)属性是数组,可以和list相互替换

<property name="num">
		<array>
			<value>1</value>
			<value>2</value>
		</array>
</property>

(4)属性是List集合时,可以和array相互替换

<property name="num">
		<list>
			<value>1</value>
			<value>2</value>
		</list>
</property>

(5)属性是set集合

<property name="num">
		以上是关于学习Spring的主要内容,如果未能解决你的问题,请参考以下文章

Spring框架学习spring整合hibernate

Spring 学习其三:数据库编程

Spring 注解版 学习笔记AnnotationConfigApplicationContext

Spring学习1:初识控制反转(IOC)——Hello,Spring

spring是什么

Spring IOC 学习总结