从零到英雄:使用Spring打造强大的企业级应用-上

Spring简介

Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。 目前是JavaEE开发的灵魂框架。他可以简JavaEE开发,可以非常方便整合其他框架,无侵入的进行功能增强。
Spring的核心就是 控制反转(IoC)和面向切面(AOP)

官网|官方下载地址|GitHub

IOC控制反转

概念

控制反转,之前对象的控制权在类手上,现在反转后到了Spring手上。

入门案例

①导入依赖

导入SpringIOC相关依赖

<dependency>
   <groupId>org.springframeworkgroupId>
    <artifactId>spring-contextartifactId>
    <version>5.1.9.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.1.10.RELEASEversion>
dependency>

②编写一个Hello实体类

public class Hello {
    private String name;
   //省略get、set
    public void showName(){
        System.out.println("Hello,"+ name );
    }
}

③编写配置文件
在resources目录下创建applicationContext.xml文件,文件名可以任意取。但是建议叫applicationContext。


<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="hello" class="com.yu.pojo.Hello">
        <property name="name" value="奇遇少年"/>
    bean>

beans>

④创建容器从容器中获取对象并测试

public class SpringTest {
    public static void main(String[] args) {
        //解析beans.xml文件 , 生成管理相应的Bean对象
        //创建Spring容器,指定要读取的配置文件路径
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //getBean : 参数即为spring配置文件中bean的id .
        //从容器中获取对象
        Hello hello = (Hello) context.getBean("hello");
        //调用对象的方法进行测试
        hello.showName(); //Hello,奇遇少年
    }
}

Bean的常用属性配置

① id
  • bean的唯一标识,同一个Spring容器中不允许重复
② class
  • 全类名,用于反射创建对象
③ scope

scope主要有两个值:singletonprototype

  • 如果设置为singleton则一个容器中只会有这个一个bean对象。默认容器创建的时候就会创建该对象。
  • 如果设置为prototype则一个容器中会有多个该bean对象。每次调用getBean方法获取时都会创建一个新对象。

scope非主要有两个值:RequestSession

  • 当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。
  • 当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

DI依赖注入

依赖注入可以理解成IoC的一种应用场景,反转的是对象间依赖关系维护权。

①set方法注入

在要注入属性的bean标签中进行配置。前提是该类有提供属性对应的set方法。

public class User {
    private String name;
    private Hello hello;
    //省略get、set
}
  
    <bean id="hello" class="com.yu.pojo.Hello">
        <property name="name" value="奇遇少年"/>
    bean>

    <bean id="user" class="com.yu.pojo.User">
        
        <property name="name" value="奇遇少年"/>
        <property name="hello" ref="hello" />
    bean>

②有参构造注入

applicationContext.xml有三种方式编写


<bean id="user" class="com.yu.pojo.User">
   
   <constructor-arg index="0" value="奇遇少年"/>
bean>

<bean id="user" class="com.yu.pojo.User">
   
   <constructor-arg name="name" value="奇遇少年"/>
bean>

<bean id="user" class="com.yu.pojo.User">
   <constructor-arg type="java.lang.String" value="奇遇少年"/>
bean>

③复杂类型属性注入

导入依赖

<dependency>
  <groupId>org.projectlombokgroupId>
   <artifactId>lombokartifactId>
   <version>1.18.28version>
dependency>

创建实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int age;
    private String name;
    private Phone phone;
    private List<String> list;
    private List<Phone> phones;
    private Set<String> set;
    private Map<String, Phone> map;
    private int[] arr;
    private Properties properties;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Phone {
    private double price;
    private String name;
    private String password;
    private String path;
}

配置如下:


<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 class="com.yu.pojo.Phone" id="phone">
        <property name="price" value="9999">property>
        <property name="name" value="华为mate 60">property>
        <property name="password" value="666">property>
        <property name="path" value="www">property>
    bean>

    <bean class="com.yu.pojo.User" id="user">
        <property name="age" value="10">property>
        <property name="name" value="大队长">property>
        <property name="phone" ref="phone">property>
        <property name="list">
            <list>
                <value>奇遇少年value>
                <value>奇遇少女value>
            list>
        property>

        <property name="phones">
            <list>
                <ref bean="phone">ref>
            list>
        property>

        <property name="set">
            <set>
                <value>setEle1value>
                <value>setEle2value>
            set>
        property>

        <property name="map">
            <map>
                <entry key="k1" value-ref="phone">entry>
                <entry key="k2" value-ref="phone">entry>
            map>
        property>

        <property name="arr">
            <array>
                <value>10value>
                <value>11value>
            array>
        property>

        <property name="properties">
            <props>
                <prop key="k1">v1prop>
                <prop key="k2">v2prop>
            props>
        property>
    bean>
beans>

SPEL

我们可以再配置文件中使用SPEL表达式。写法如下:

<property name="age" value="#{...}"/>

​ 注意:SPEL需要写到value属性中,不能写到ref属性。
配置文件

p命名和c命名注入

User.java :注意:这里没有有参构造器!

 public class User {
     private String name;
     
     public void setName(String name) {
         this.name = name;
    }
 
     @Override
     public String toString() {
         .....
    }
 }

P命名空间注入

需要在头文件中加入约束文件

 导入约束 : xmlns:p="http://www.springframework.org/schema/p"
 
 
 <bean id="user" class="com.yu.pojo.User" p:name="奇遇少年"/>

c 命名空间注入

需要在头文件中加入约束文件

导入约束 : xmlns:c="http://www.springframework.org/schema/c"
 
 <bean id="user" class="com.yu.pojo.User" c:name="奇遇少年" />

发现问题:爆红了,刚才我们没有写有参构造!

解决:把有参构造器加上,这里也能知道,c 就是所谓的构造器注入!
测试代码:

public class SpringTest {
    public static void main(String[] args) {
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
     User user = (User) context.getBean("user");
     System.out.println(user);
 	}
 }

配置文件

读取properties文件

​ 我们可以让Spring读取properties文件中的key/value,然后使用其中的值。

①设置读取properties

在Spring配置文件中加入如下标签:指定要读取的文件的路径。

<context:property-placeholder location="classpath:filename.properties">

其中的classpath表示类加载路径下。

我们也会用到如下写法:classpath:**.properties 其中的* * 表示文件名任意。

注意:context命名空间的引入是否正确

②使用配置文件中的值

在我们需要使用的时候可以使用${key}来表示具体的值。注意要再value属性中使用才可以。例如:

<property name="propertyName" value="${key}"/>
③别名

alias 设置别名 , 为bean设置别名 , 可以设置多个别名

<alias name="user" alias="user01"/>



<bean id="hello" name="hello2 h2,h3;h4" class="com.yu.pojo.Hello">
   <property name="name" value="奇遇少年"/>
bean>

低频知识点

①bean的配置

name属性
我们可以用name属性来给bean取名。例如:

<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource" name="dataSource2,dataSource3">
      <property name="driverClassName" value="${jdbc.driver}">property>
      <property name="url" value="${jdbc.url}">property>
      <property name="username" value="${jdbc.username}">property>
      <property name="password" value="${jdbc.password}">property>
  bean>

获取的时候就可以使用这个名字来获取了

 public static void main(String[] args) {

        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        DruidDataSource dataSource = (DruidDataSource) app.getBean("dataSource3");
        System.out.println(dataSource);

    }

② lazy-init

可以控制bean的创建时间,如果设置为true就是在第一次获取该对象的时候才去创建。

<bean class="com.alibaba.druid.pool.DruidDataSource" lazy-init="true"  id="dataSource" name="dataSource2,dataSource3">
    <property name="driverClassName" value="${jdbc.driver}">property>
    <property name="url" value="${jdbc.url}">property>
    <property name="username" value="${jdbc.username}">property>
    <property name="password" value="${jdbc.password}">property>
bean>

③init-method

可以用来设置初始化方法,设置完后容器创建完对象就会自动帮我们调用对应的方法。

<bean class="com.yu.pojo.User" id="user" init-method="init">bean>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User{

    private String name;
	//初始化方法
    public void init(){
        System.out.println("对用户对象进行初始化操作");
    }

}

注意:配置的初始化方法只能是空参的。

④destroy-method

可以用来设置销毁之前调用的方法,设置完后容器销毁对象前就会自动帮我们调用对应的方法。

  <bean class="com.yu.pojo.User" id="user"  destroy-method="close">bean>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User{

    private String name;
	//初始化方法
    public void init(){
        System.out.println("对用户对象进行初始化操作");
    }
    public void close(){
        System.out.println("对象销毁之前调用,用于释放资源");
    }

}

注意:配置的方法只能是空参的。

⑤factory-bean&factory-method

当我们需要让Spring容器使用工厂类来创建对象放入Spring容器的时候可以使用factory-bean和factory-method属性。

⑥配置实例工厂创建对象

配置文件中进行配置


    <bean class="com.yu.factory.CarFactory" id="carFactory">bean>
    
    
    
    <bean factory-bean="carFactory" factory-method="getCar" id="car">bean>
   ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取car对象
        Car c = (Car) app.getBean("car");
        System.out.println(c);

⑦配置静态工厂创建对象

配置文件中进行配置

 
    <bean class="com.yu.factory.CarStaticFactory" factory-method="getCar" id="car2">bean>

创建容器获取对象测试

  ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取car对象
        Car c = (Car) app.getBean("car2");
        System.out.println(c);

拓展

Spring Boot与Spring Cloud

  • Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务;
  • Spring Cloud是基于Spring Boot实现的;
  • Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;
  • Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置 , Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
  • SpringBoot在SpringClound中起到了承上启下的作用,如果你要学习SpringCloud必须要学习SpringBoot。

你可能感兴趣的:(Spring,spring,java,后端)