3.2spring基础入门

本文详细介绍了Spring框架的核心特性,包括IoC容器、Bean的创建与管理、依赖注入的三种方式(构造函数、set方法、注解)、Bean的作用域与生命周期,以及注解配置与XML配置的区别。通过实例展示了如何创建Bean、获取Bean以及测试Bean的操作。此外,还探讨了Spring框架的优势,如解耦、AOP支持、声明式事务管理和与其他框架的集成。
摘要由CSDN通过智能技术生成

1.spring简述

1.spring

Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。

2.spring优势

  • 方便解耦,简化开发
    通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
  • AOP 编程的支持
    通过 Spring 的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。
  • 声明式事务的支持
    可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
  • 方便程序的测试
    可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
  • 方便集成各种优秀框架
    Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
  • 降低 JavaEE API 的使用难度
    Spring 对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。
  • Java 源码是经典学习范例
    Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。

2.ioc环境搭建

【1】创建 maven 版的 Java 工程

搭建好后目录结构如下:

在这里插入图片描述

【2】导入 jar 包

在pom.xml中加入相关依赖,导入Spring相关jar包(为了方便后面进行测试,这里导入了测试jar包)

<packaging>jar</packaging>
 
    <dependencies>
        <!--导入Spring相关jar包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--导入测试相关jar包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

【3】创建 Spring 配置文件

在 resources 目录下创建配置文件,内容如下(可以从Spring官网获取)

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

【4】创建实体类

创建一个简单的HelloWorld类

public class Helloworld {
    private String name;
    public Helloworld(){
        System.out.println("创建对象");
    }
    public void setName(String name) {
        System.out.println("调用方法");
        this.name = name;
    }
    public void sayHello(){
        System.out.println("Hello!" + name);
    }
}

【5】对类进行配置

配置之后如下

<?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属性:给当前bean起一个名称,该名称必须保证是唯一的
        class属性:设置bean的全类名-->
    <bean id="helloworld" class="com.LSTAR.Helloworld">
        <!--给属性赋值
            name属性:设置bean属性名
            value属性:设置bean属性值-->
        <property name="name" value="LSTAR"></property>
    </bean>
</beans>

【6】测试类

public class test {
@Test
    public void test(){
        //1.创建IOC容器对象
        ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.从IOC容器中获取Helloworld对象
        Helloworld hello = (Helloworld) ioc.getBean("helloworld");
        //3.调用类中方法
        hello.sayHello();
    }
}

2.spring Bean

bean.xml:

1.创建bean的三种方式

  • 第一种方式:使用默认构造函数创建。
    在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。
    采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。
  <bean id="accountService" class="service.impl.AccountServiceImpl"></bean>
  • 第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器
   <bean id="instanceFactory" class="factory.InstanceFactory"></bean>
     <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
  • 第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
<bean id="accountService" class="factory.StaticFactory" factory-method="getAccountService"></bean>

2.获取bean的三种方式

配置文件就是让IOC容器能够来管理一个具体的对象,主要就是通过配置进行管理,Spring 能够通过获取的配置来获取到对应的对象以及属性,中 id 表示唯一属性,class 表示类的全类名,通过反射的方式创建对象:

Class class = Class.forName("com.LSTAR.Helloworld");
Object obj = class.newlnstance();    //无参构造函数

获取bean有三种方式

  • 【1】根据 id 获取

通过唯一标识 id 来获取,上面的环境搭建就是用的这种方式

Helloworld hello = (Helloworld) ioc.getBean("helloworld");
  • 【2】通过 bean 类型获取

如果同一个类型的bean在xml文件中配置了多个,则获取时会抛出异常,所以同一个类型的bean在容器中必须是唯一的

Helloworld hello = ioc.getBean(Helloworld.class);
  • 【3】指定bean的 id 值和类型
Helloworld hello = ioc.getBean("helloworld",Helloworld.class);

3.bean对象作用范围

bean的作用范围调整

bean标签的scope属性:
作用:用于指定bean的作用范围
取值: 常用的就是单例的和多例的

singleton:单例的(默认值)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session 
  <bean id="accountService" class="service.impl.AccountServiceImpl" scope="prototype"></bean>

4.bean对象生命周期

bean对象的生命周期

  • 单例对象
    出生:当容器创建时对象出生
    活着:只要容器还在,对象一直活着
    死亡:容器销毁,对象消亡
    总结:单例对象的生命周期和容器相同
  • 多例对象
    出生:当我们使用对象时spring框架为我们创建
    活着:对象只要是在使用过程中就一直活着。
    死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
<bean id="accountService" class="service.impl.AccountServiceImpl"
      scope="prototype" init-method="init" destroy-method="destroy">
</bean>

3. spring依赖注入

  • 依赖注入:
    Dependency Injection

  • IOC的作用:
    降低程序间的耦合(依赖关系)

  • 依赖关系的管理:
    以后都交给spring来维护
    在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明

  • 依赖关系的维护:
    就称之为依赖注入。

  • 依赖注入:
    能注入的数据:有三类

      基本类型和String
      其他bean类型(在配置文件中或者注解配置过的bean)
      复杂类型/集合类型
    
  • 注入的方式:有三种

  •   第一种:使用构造函数提供
      第二种:使用set方法提供
      第三种:使用注解提供
    

1.构造函数注入

构造函数注入:

  • 使用的标签:constructor-arg

  • 标签出现的位置:bean标签的内部

  • 标签中的属性

      type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
      index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
      name:用于指定给构造函数中指定名称的参数赋值                                        常用的
    

    ============= 以上三个用于指定给构造函数中哪个参数赋值===============================

      value:用于提供基本类型和String类型的数据
      ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
    

    优势:
    在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
    弊端:
    改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。

 <bean id="now" class="java.util.Date"></bean>

    <bean id="accountService" class="service.impl.AccountServiceImpl">
        <constructor-arg name="name" value="泰斯特"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="birthday" ref="now"></constructor-arg>
    </bean>

2、set 方法注入

使用 set 注入需要在类中创建 set 方法,在 bean 标签中使用 标签,可以通过 value 属性和 ref 属性进注入:

通过 value 属性注入:一般的数据类型都可以通过 value 属性进行赋值
通过 ref 注入:对象输数据则可以通过 ref 进行赋值

比如:在学校类中除了有年龄,姓名属性,还有老师对象属性,对于年龄、姓名属性可以直接使用 value属性进行赋值,而老师对象则需要通过 ref 进行赋值

   <!-- set方法注入                更常用的方式
       涉及的标签:property
       出现的位置:bean标签的内部
       标签的属性
           name:用于指定注入时所调用的set方法名称
           value:用于提供基本类型和String类型的数据
           ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
       优势:
           创建对象时没有明确的限制,可以直接使用默认构造函数
       弊端:
           如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
   -->
    <bean id="accountService2" class="service.impl.AccountServiceImpl2">
        <property name="name" value="TEST"></property>
        <property name="age" value="21"></property>
        <property name="birthday" ref="now"></property>
    </bean>

3、集合注入

使用集合注入,首先在类中创建集合成员变量和set方法,这里创建了String[]数组集合、List集合、Set集合、Map集合、Properties集合,并生成了相应的set和toString方法,接下来对xml配置文件进行bean的配置,配置如下:

  复杂类型的注入/集合类型的注入
      用于给List结构集合注入的标签:
          list array set
      用于个Map结构集合注入的标签:
          map  props
      结构相同,标签可以互换
<bean id="accountService3" class="service.impl.AccountServiceImpl3">
    <property name="mystrs">
        <set>
            <value>a</value>
            <value>bb</value>
            <value>ccc</value>
        </set>
    </property>

    <property name="mylist">
        <list>
            <value>a</value>
            <value>bb</value>
            <value>ccc</value>
        </list>
    </property>

    <property name="myset">
        <set>
            <value>a</value>
            <value>bb</value>
            <value>ccc</value>
        </set>
    </property>

    <property name="mymap">
        <map>
            <entry key="testA" value="a"></entry>
            <entry key="testB">
                <value >bb</value>
            </entry>
        </map>
    </property>

    <property name="mypro">
        <props>
            <prop key="testA">a</prop>
            <prop key="testB">bb</prop>
        </props>
    </property>
</bean>

4.注解配置

1、创建Spring配置文件

使用Spring注解配置需要需要配置自动扫描的包,让Spring知道配置文件是哪一个,配置如下:

<?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
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!--设置自动扫描的包
        base-package属性:设置一个基础包,Spring会自动扫描该包及其子包-->
    <context:component-scan base-package="com.LSTAR"></context:component-scan>
</beans>

2、注解配置

【0】pom.xml:

<packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.2</version>
        </dependency>

【0】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"
       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
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为
    context名称空间和约束中-->
    <context:component-scan base-package="service"/>
    <context:component-scan base-package="dao"/>

</beans>
 曾经XML的配置:
 *  <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
 *        scope=""  init-method="" destroy-method="">
 *      <property name=""  value="" | ref=""></property>
 *  </bean>

【1】创建对象注解

@Component

  • 作用:用于把当前对象存入Spring 容器中
  • 属性:value==>用于指定 bean 的 id,当不写时,默认为当前类名,首写字母改为小写
  • @Controller、@Service、@Repository这三个注解的作用和@Component注解是一样的,他们是Spring框架为我们提供明确的三层使用注解,使三层对象更加清晰
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

}
  • @Controller:一般用于表现层
  • @Service:一般用于业务层
  • @Repository:一般用于持久层

【2】注入数据注解

@Value

  • 作用:用于注入基本类型和String类型的数据
  • 属性:value==>用于指定数据的值,它可以使用spring找那个SpEL(Spring中的el表达式):${表达式}

@Autowired

  • 作用:注入其他bean类型(不能注入基本类型和String类型),自动按照类型注入,只要容器中有唯一的一个 bean 对象类型和要注入的变量类型匹配,就可以注入成功,如果IOC容器中有多个类型匹配时,先按照类型找到匹配的对象,然后使用变量名称作为bean的id继续查找
    位置:可以是变量上,也可以是方法上
    在使用注解配置时,set方法就不是必须的了
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao2 = null;
	...
}

@Qualifier

  • 作用:在按照类型注入的基础上再按照名称注入,它在给类成员注入时不能单独使用,但在给方法参数注入时可以
  • 属性:value==>用于指定注入 bean 的 id
public class AccountServiceImpl implements AccountService {
    @Autowired
    @Qualifier("accountDao")
    private AccountDao accountDao2 = null;
    ...
}

@Resource

  • 作用:直接按照 bean 的 id 注入,可以独立使用
    属性:name==>用于指定 bean 的 id
public class AccountServiceImpl implements AccountService {
    @Resource(name = "accountDao2")
    private AccountDao accountDao2 = null;
    ...
}

注:
@Autowired、@Qualifier、@Resource都只能注入其他bean类型的数据,基本类型和String类型无法使用这三个来进行注解,需要使用@Value来注解
集合类型只能通过xml来实现

【3】改变作用范围注解

@Scope

作用:用于指定 bean 的作用范围
属性:value==>指定范围的取值,常用取值
singleton:单例(默认)
prototype:多例

@Scope("prototype")
public class AccountServiceImpl implements AccountService {
	...
}

【4】生命周期相关注解

@PreDestroy:用于指定销毁方法
@PostConstruct:用于指定初始化方法

public class AccountServiceImpl implements AccountService {
    @PostConstruct
    public void init() {
        System.out.println("初始化...");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("销毁方法执行 ...");
    }
}

spring与xml配置区别

  • 注解的优势:
    配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。
  • XML 的优势:
    修改时,不用改源码。不涉及重新编译和部署。
    Spring 管理 Bean 方式的比较:
    在这里插入图片描述

3.spring新注解

5.使用spring的ioc实现账户的CRUD操作

【0】sql准备

CREATE TABLE account(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(40),
	money FLOAT
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO account(NAME,money) VALUES('aaa',1000);
INSERT INTO account(NAME,money) VALUES('bbb',1000);
INSERT INTO account(NAME,money) VALUES('ccc',1000);

【1】
实现类:

public class Account {
    private Integer id;
    private String name;
    private float money;
 }   

【2】
service:

/**
 * 账户的业务层接口
 */
public interface AccountService {
    List<Account> findAllAccount();
    Account findAccountById(Integer accountId);
    void saveAccount(Account account);
    void updateAccount(Account account);
    void deleteAccount(Integer acccountId);
}
public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao = null;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    
    @Override
    public List<Account> findAllAccount() {
        List<Account> accounts = accountDao.findAllAccount();
        return accounts;
    }
    @Override
    public Account findAccountById(Integer accountId) {
        Account account = accountDao.findAccountById(accountId);
        return account;
    }
    @Override
    public void saveAccount(Account account) {
        accountDao.saveAccount(account);
    }
    @Override
    public void updateAccount(Account account) {
        accountDao.updateAccount(account);
    }
    @Override
    public void deleteAccount(Integer acccountId) {
        accountDao.deleteAccount(acccountId);
    }
}

【3】dao:

public interface AccountDao {
    List<Account> findAllAccount();
    Account findAccountById(Integer accountId);
    void saveAccount(Account account);
    void updateAccount(Account account);
    void deleteAccount(Integer acccountId);
}
public class AccountDaoImpl implements AccountDao {
    private QueryRunner runner = null;

    public void setRunner(QueryRunner runner) {
        this.runner = runner;
    }

    @Override
    public List<Account> findAllAccount() {
        try {
            return runner.query("select * from account ", new BeanListHandler<Account>(Account.class));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Account findAccountById(Integer accountId) {
        try {
            return runner.query("select * from account where id = ? ",
                    new BeanHandler<Account>(Account.class), accountId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void saveAccount(Account account) {
        try {
            runner.update(" insert into account(name,money) values(? , ? ) ",
                    account.getName(), account.getMoney());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void updateAccount(Account account) {
        try {
            runner.update(" update account set name = ? , money = ? where id = ? ",
                    account.getName(), account.getMoney(), account.getId());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteAccount(Integer acccountId) {
        try {
            runner.update(" delete from account where id = ? ", acccountId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

【4】重点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">


    <!-- 配置Service -->
    <bean id="accountService" class="service.impl.AccountServiceImpl">
        <!-- 注入dao -->
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!--配置Dao对象-->
    <bean id="accountDao" class="dao.impl.AccountDaoImpl">
        <!-- 注入QueryRunner -->
        <property name="runner" ref="runner"></property>
    </bean>

    <!--配置QueryRunner-->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <!--注入数据源-->
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>
    <!-- 配置数据源 -->
    <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/spring"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

</beans>

【5】test测试类

public class AccountTest {
    private ClassPathXmlApplicationContext cs;
    private AccountService accountService;

    @Before
    public void init() {
        cs = new ClassPathXmlApplicationContext("bean.xml");
        accountService = cs.getBean("accountService", AccountServiceImpl.class);
    }

    @Test
    public void testFindAll() {
        List<Account> allAccounts = accountService.findAllAccount();
        for (Account allAccount : allAccounts) {
            System.out.println(allAccount);
        }
    }

    @Test
    public void testFindOne() {
        Account account = accountService.findAccountById(2);
        System.out.println(account);
    }

    @Test
    public void testSave() {
        Account account = new Account();
        account.setName("太斯克");
        account.setMoney(12345l);
        accountService.saveAccount(account);
    }

    @Test
    public void testUpdate() {
        Account account = accountService.findAccountById(4);
        account.setMoney(12l);
        accountService.updateAccount(account);
    }

    @Test
    public void testDelete() {
        accountService.deleteAccount(4);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值