Spring

Spring 是什么?

Spring 是于 2003 年兴起的一个轻量级的,IOC 和 AOP 的 Java 开发框架,它 是为了简化企业级应用开发而生的。

Spring 优点

轻量级:Spring框架使用的jar都比较小,一般在1M以下或者几百kb。Spring 核心功能所选的jar总共3M左右,框架运行占用资源较少,运行效率高。
非侵入式: 编写一些业务类的时候不需要继承 spring 特定类,通过配置完成依赖注入后就可以使用。
IOC (Inversion of Control),就是由 Spring IOC 容器管理对象,而 非传统实现中由程序代码直接操控,面向接口式编程,使得耦合度降低。
AOP:通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传 统 OOP 实现的功能可以通过 AOP 轻松应付在 Spring 中,开发人员可以从 繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高 开发效率和质量。

Spring Hello World 搭建

预备工作:

  1. 新建一个普通的java项目,命名为spring。
  2. 在项目中新建一个Modual,在modual中新建一个项目命名为 spring1。
  3. 在pom.xml的dependencies中添加常用jar包,如spring-context和junit等。
  4. 在resources下新建spring.xml,bean.xml

新建Phone类

package com.ff.spring.bean;

public class Phone {
}

新建user类

package com.ff.spring.bean;
public class User {
    private  int id;
    private String name;
    private Phone phone;

    public User() {
        System.out.println("构造方法");
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }
}

bean.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">
<import resource="bean.xml"></import>

</beans>

spring.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">
    <!--
        <bean id="user" class="com.ff.spring.bean.User" scope="singleton"></bean>
    -->
    <!-- scope 对象生产的作用域 scope="singleton" 一个项目中只有一个该对象,而且是在容器创建时就会创建对象-->
    <!--scope="prototype" 原型的(多例的) 每次使用时都会创建一个新的对象,在get时创建-->

    <bean id="phone" class="com.ff.spring.bean.Phone" scope="prototype"></bean>
    <bean id="user" class="com.ff.spring.bean.User" scope="prototype">
        <property name="id" value="21"></property>
        <property name="name" value="xaiom"></property>
        <property name="phone"  ref="phone"></property>
    </bean>

新建一个测试类

package com.ff.spring.test;

import com.ff.spring.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main(String[] args) {
        // 创建spring容器  ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user1 = (User) applicationContext.getBean("user");
        System.out.println(user1);
        User user2 = (User) applicationContext.getBean("user");
        System.out.println(user2);
    }
}

运行截图

因为 spring.xml的scope的值为prototype,因此每创建一个对象都执行一次构造方法,且每次使用时都会创建一个新的对象。

若将scope属性的值改为singleton,则一个项目中只有一个该对象,而且是在容器创建时就会创建对象执行一次构造方法。

spring 生成指定参数的构造函数 spring有参构造方法注入注解_java

eg2:使用set方法向属性注入值

新建Phone类

package com.ff.spring.bean;

public class Phone {
}

新建user类

package com.ff.spring.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class User {
    private  int id;
    private String name;
    private Phone phone;

    private Set sett;
    private List list;
    private Map map;
    private Properties properties;

    public User() {
        System.out.println("构造方法");
    }

    public User(int id) {
        this.id= id;
    }

    public User(int id, String name) {
        this.id=id;
        this.name=name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    public Set getSett() {
        return sett;
    }

    public void setSett(Set sett) {
        this.sett = sett;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", phone=" + phone +
                ", sett=" + sett +
                ", list=" + list +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

spring.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">
<import resource="bean.xml"></import>

</beans>

bean.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">
    <!--
        <bean id="user" class="com.ff.spring.bean.User" scope="singleton"></bean>
    -->
    <!-- scope 对象生产的作用域 scope="singleton" 一个项目中只有一个该对象,而且是在容器创建时就会创建对象-->
    <!--scope="prototype" 原型的(多例的) 每次使用时都会创建一个新的对象,在get时创建-->

    <!--XML 配置方式依赖注入 DI(Dependency Injection)
    注入方式:1.set方式注入
    2.用构造方法注入-->

    <bean id="phone" class="com.ff.spring.bean.Phone" scope="prototype"></bean>
    <bean id="user" class="com.ff.spring.bean.User" scope="prototype">
            <property name="id" value="21"></property>
            <property name="name" value="xaiom"></property>
            <property name="phone"  ref="phone"></property>

           <property name="list">
               <list>
                   <value>list1</value>
                   <value>list2</value>
                   <value>list2</value>
               </list>
           </property>

            <property name="sett">
                <set>
                    <value>set1</value>
                    <value>set2</value>
                    <value>set3</value>
                </set>
            </property>

            <property name="map">
                <map>
                    <entry key="map1" value="map1"></entry>
                    <entry key="map2" value="map2"></entry>
                    <entry key="map3" value="map3"></entry>
                </map>
            </property>

            <property name="properties">
              <props>
                  <prop key="key1" >value1</prop>
                  <prop key="key2" >value2</prop>
                  <prop key="key3" >value3</prop>
              </props>
            </property>
        </bean>

    </beans>
</beans>

测试类

package com.ff.spring.test;

import com.ff.spring.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main(String[] args) {
        // 创建spring容器  ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user1 = (User) applicationContext.getBean("user");
        System.out.println(user1);
        User user2 = (User) applicationContext.getBean("user");
        System.out.println(user2);
    }
}

运行截图

spring 生成指定参数的构造函数 spring有参构造方法注入注解_maven_02

eg3:使用构造方法向属性注入值

Phone类

package com.ff.spring.bean;

public class Phone {
}

user类

package com.ff.spring.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class User {
    private  int id;
    private String name;
    private Phone phone;

    private Set sett;
    private List list;
    private Map map;
    private Properties properties;

    public User() {
        System.out.println("构造方法");
    }

    public User(int id) {
        this.id= id;
    }

    public User(int id, String name) {
        this.id=id;
        this.name=name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    public Set getSett() {
        return sett;
    }

    public void setSett(Set sett) {
        this.sett = sett;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", phone=" + phone +
                ", sett=" + sett +
                ", list=" + list +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

spring.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">
<import resource="bean.xml"></import>

</beans>

bean.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">
    <!--
        <bean id="user" class="com.ff.spring.bean.User" scope="singleton"></bean>
    -->
    <!-- scope 对象生产的作用域 scope="singleton" 一个项目中只有一个该对象,而且是在容器创建时就会创建对象-->
    <!--scope="prototype" 原型的(多例的) 每次使用时都会创建一个新的对象,在get时创建-->

    <!--XML 配置方式依赖注入 DI(Dependency Injection)
    注入方式:1.set方式注入
    2.用构造方法注入-->

    <bean id="phone" class="com.ff.spring.bean.Phone" scope="prototype"></bean>
    <bean id="user" class="com.ff.spring.bean.User" scope="singleton">
        <constructor-arg name="id" value="111"></constructor-arg>
        <constructor-arg name="name" value="xx"></constructor-arg>
    </bean>

</beans>

测试类

package com.ff.spring.test;

import com.ff.spring.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main(String[] args) {
        // 创建spring容器  ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user1 = (User) applicationContext.getBean("user");
        System.out.println(user1);
        User user2 = (User) applicationContext.getBean("user");
        System.out.println(user2);
    }
}

运行截图

spring 生成指定参数的构造函数 spring有参构造方法注入注解_spring_03

eg4:使用注解的方式

复制spring1这个module,在项目根粘贴,命名为spring2,修改pom.xml中的name为spring2。
此时我们会发现这个复制出来的项目比原来创建的module字体颜色浅,需要做以下的设置。
file->Project Structure->Modules->"+"->import Module->选择spring2->Maven->改名字->apply->ok

Phone类

package com.ff.spring.bean;

public class Phone {
}

User类

package com.ff.spring.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class User {
    private  int id;
    private String name;
    private Phone phone;

    private Set sett;
    private List list;
    private Map map;
    private Properties properties;

    public User() {
        System.out.println("构造方法");
    }

    public User(int id) {
        this.id= id;
    }

    public User(int id, String name) {
        this.id= id;
        this.name=name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    public Set getSett() {
        return sett;
    }

    public void setSett(Set sett) {
        this.sett = sett;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", phone=" + phone +
                ", sett=" + sett +
                ", list=" + list +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

userDao

package com.ff.spring.Dao;

import org.springframework.stereotype.Repository;

@Repository (value = "userDao")

public class UserDao {
    public  void save(){
        System.out.println("保存员工信息");
    }
}

UserService

package com.ff.spring.service;

import com.ff.spring.Dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
   @Autowired
   UserDao userDao;
    public void save(){
        userDao.save();
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

spring.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
       https://www.springframework.org/schema/context/spring-context.xsd">
    <!--spring开启注解扫描-->
     <!--若加入下面这一行后有错,需要加约束条件
     xmlns:context="http://www.springframework.org/schema/context"
     http://www.springframework.org/schema/context
     https://www.springframework.org/schema/context/spring-context.xsd
    -->
    <context:component-scan base-package="com.ff.spring"></context:component-scan>
</beans>

新建测试类:

package com.ff.spring.test;

import com.ff.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*
IOC控制反转 也叫做反转控制
把创建对象的控制权反转给spring框架/容器
 */
public class Test2 {
    public static void main(String[] args) {
        // 创建spring容器  ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.save();
        UserService userService1= applicationContext.getBean("userService",UserService.class);
        userService1.save();
    }
}

运行结果:

spring 生成指定参数的构造函数 spring有参构造方法注入注解_spring_04

Spring JDBC

预备工作:

  1. 用上面的方式新建module命名为spring3
  2. 删除最下面的spring2.iml

在pom.xml中加jar的坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>spring2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>spring3</name>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <junit.version>5.6.2</junit.version>
    </properties>

    <dependencies>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>provided</scope>
        </dependency>

        <!-- mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <!-- spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>
        <!-- 阿里数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--spring-mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
        </plugins>
    </build>
</project>

新建spring.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
       https://www.springframework.org/schema/context/spring-context.xsd">
    <!--spring开启注解扫描-->
    <context:component-scan base-package="com.ff.spring"></context:component-scan>
    <import resource="db.xml"></import>
</beans>

新建db.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
       https://www.springframework.org/schema/context/spring-context.xsd">
   <!--读取属性文件-->
    <context:property-placeholder location="config.properties"></context:property-placeholder>
    <!--spring生产数据库连接管理对象-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${drivername}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${uname}"></property>
        <property name="password" value="${password}"></property>
        <property name="initialSize" value="5"></property>
        <property name="minIdle" value="5"></property>
        <property name="maxActive" value="20"></property>
    </bean>
    <!--spring提供的jdbc支持-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
</beans>

新建config.properties

drivername=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybaits?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
uname=root
password=13579

新建JdbcUtil.java

package com.ff.spring.test;

import com.alibaba.druid.pool.DruidDataSource;

import java.sql.Connection;
import java.sql.SQLException;

public class JdbcUtil {
    public Connection getConnection() throws SQLException {
        DruidDataSource druidDataSource= new DruidDataSource();
        druidDataSource.setUrl("");
        druidDataSource.setUsername("");
        druidDataSource.setPassword("");
        druidDataSource.setDriverClassName("");

        return druidDataSource.getConnection();//从连接池中获取的
    }
}

User

package com.ff.spring.bean;

import org.springframework.stereotype.Component;

@Component
public class User {
    private  int id;
    private String name;

}

UserDao

package com.ff.spring.Dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;


@Repository

public class UserDao {
    @Autowired
    JdbcTemplate jdbcTemplate;
    public  void save(){

        jdbcTemplate.update("insert into dept(name) values ('后勤部')");
    }
}

新建UserService

package com.ff.spring.service;

import com.ff.spring.Dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service(value="userService")
public class UserService {
  @Autowired
   UserDao userDao;
    public void save(){
        userDao.save();
    }

}

新建测试Test1

package com.ff.spring.test;

import com.ff.spring.bean.User;
import com.ff.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main(String[] args) {
      ApplicationContext context= new ClassPathXmlApplicationContext("spring.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.save();
    }
}

运行结果:

spring 生成指定参数的构造函数 spring有参构造方法注入注解_User_05

数据库中插入结果

spring 生成指定参数的构造函数 spring有参构造方法注入注解_User_06