【SSM】Spring学习笔记-DAY2

2.1 Bean的配置

最常用XML文件来注册并管理Bean之间的依赖关系。
XML配置文件的根元素是< beans >,其中包含很多个< bean >子元素,每一个子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。
在Spring的配置文件中,通常一个普通的Bean只需要定义id(或name)和class两个属性即可。
元素常用属性和子元素

如果在Bean中未指定id和name,那么Spring会将class值当做id来使用

2.2 Bean的作用域

2.2.1 作用域的种类

Bean的作用域其中singleton和prototype是常用的两种。

2.2.2 singleton作用域

singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean的id属性相匹配,就会返回同一个Bean的实例。
Bean的作用域是通过< bean>元素的scope属性来选择的。

<bean id="scope" class="com.ssm.scope.Scope" scope="singleton"/>

示例 2-1

  1. 创建web项目 在示例1的基础上增加spring-aop-5.2.2.RELEASE.jar包
  2. 创建com.ssm.scope包,创建Scope类,不需要写方法。
package com.ssm.scope;

public class Scope {
}

  1. 在包中创建Spring配置文件,并在配置文件中创建一个id为Scope的Bean,通过class属性指定对应的实现类。
<?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="scope" class="com.ssm.scope.Scope"/>
</beans>

  1. 创建测试类ScopeTest来测试作用域
package com.ssm.scope;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ScopeTest {
    public static void main(String[] args){
//        1.初始化Spring容器,加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//        2.输出获得的实例
        System.out.println(applicationContext.getBean("scope"));
        System.out.println(applicationContext.getBean("scope"));
    }
}

  1. 执行程序后 输出结果如下,两次结果相同,说明Spring容器只创建了一个Scope实例。
    在这里插入图片描述

不设置scope=“singleton”输出结果也是一个实例,因为Spring容器默认作用域是singleton。

2.2.3 prototype作用域

对需要保持会话的Bean使用prototype作用域。
在使用prototype作用域时,Spring容器会为每个请求都创建一个新的实例。

<bean id="scope" class="com.ssm.scope.Scope" scope="prototype"/>

将示例2-1中的配置文件更改为上面的代码,再次运行测试类。
在这里插入图片描述两次输出结果不同,说明创建了两个不同实例。

2.3 Bean的装配方式

Bean的装配可以理解为依赖关系注入。
Bean的装配方式即Bean的依赖注入的方式。
Spring容器支持多种形式的Bean装配方式,如基于XML的装配、基于Annotation(注解)的装配和自动装配等。

2.3.1 基于XML的装配

Spring提供了两种基于XML的装配方式:设值注入构造注入
在Spring实例化Bean的过程中,Spring首先会调用Bean的默认构造方法来实例化Bean对象,然后通过反射的方式调用setter()方法来注入属性值。
因此 设值注入要求Bean满足两点要求

  • Bean类必须提供一个默认的无参构造方法。
  • Bean类必须为需要注入的属性提供对应的setter()方法。
    使用设值注入时,在Spring配置文件中需要使用< bean>元素的子元素< property>来为每个属性注入值。而使用构造注入时,在配置文件中需要使用< construcot-arg>来定义构造方法的参数,可以使用其value属性来设置参数值。

示例2-2

  1. 创建com.ssm.assemble包,创建User类,定义username、password和list集合3个属性以及对应的setter()方法。
package com.ssm.assemble;

import java.util.List;

public class User {
    private String username;
    private String password;
    private List<String> list;

    /**
     * 1.使用构造注入
     * 1.1 提供带有参数的构造方法
     */
    
    public User(String username,String password,List<String> list){
        super();
        this.username=username;
        this.password=password;
        this.list=list;
    }
    @Override
    public String toString(){
        return "User [username="+username+",password="+password+",list="+list+"]";
    }

    /**
     * 2.使用设值注入
     * 2.1 提供默认空参构造方法
     * 2.2 为所有属性提供setter()方法
     */
    
    public User(){
        super();
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

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

由于要使用构造注入 所以编写有参和无参两种构造方法。

  1. 在Spring的配置文件中,增加通过构造注入和设值注入的方法装配User实例的两个Bean。
    <bean id="user1" class="com.ssm.assemble.User">
        <constructor-arg index="0" value="zhangsan"/>
        <constructor-arg index="1" value="111111"/>
        <constructor-arg index="2" >
            <list>
                <value>"constructorValue1"</value>
                <value>"constructorValue2"</value>
            </list>
        </constructor-arg>
    </bean>
    
    <bean id="user2" class="com.ssm.assemble.User">
        <property name="username" value="lisi"/>
        <property name="password" value="222222"/>
        <property name="list">
            <list>
                <value>"listValue1"</value>
                <value>"listValue2"</value>
            </list>
        </property>
    </bean>

在上述代码中,< constructor-arg>元素用于定义构造方法的参数,其属性index表示索引(从0开始),value属性用于设置注入的值,其子元素< list>为User类对应的list集合属性注入值。
然后又使用设置注入的方法装配User类的实例,其中< property>元素用于调用Bean实例中的setter()方法完成属性赋值,从而完成依赖注入,而子元素< list>同样为User类中对应的list集合属性注入值。

  1. 在包中创建测试类XmlAssembleTest,在类中分别获取并输出配合文件中的user1和user2实例。
package com.ssm.assemble;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class XmlAssembleTest {
    public static void main(String[] args){
        //1.初始化Spring容器,加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.输出获得的实例
        System.out.println(applicationContext.getBean("user1"));
        System.out.println(applicationContext.getBean("user2"));
    }
}

运行后结果如下,已经成功地使用基于XML装配的构造注入和设值注入两种方式装配了User实例
在这里插入图片描述

2.3.2 基于Annotation的装配

Spring常用注解

虽然@Repository、@Service和@Controller的功能与@Component注解的功能相同,但为了使标注类本身用提更加清晰,建议使用@Repository、@Service和@Controller分别进行标注


示例2-3

  1. 创建com.ssm.annotation包,创建接口UserDao,在接口中定义save()方法。
package com.ssm.annotation;

public interface UserDao {
    public void save();
}

  1. 创建接口实现类
package com.ssm.annotation;

import org.springframework.stereotype.Repository;
//使用@Repository注解将UserDaoImpl类标识为Bean
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("userDao.save()");
    }
}

@Repository注解将UserDaoImpl标识为Bean,其写法相当于配置文件中的<bean id="userDao" class="com.ssm.annotation.UserDaoImol"/>
然后在save方法中打印一句话,用于验证。

  1. 创建接口UserService,在接口中定义save方法
package com.ssm.annotation;

public interface UserService {
    public void save();
}

  1. 创建实现类
package com.ssm.annotation;

import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

//使用@Service注解将UserServiceImpl标识为Bean
@Service("userService")
public class UserServiceImpl implements UserService {
    //使用@Resource注解注入
    @Resource
    private UserDao userDao;
    public void save() {
        this.userDao.save();
        System.out.println("执行userService.save()");
    }
}

这里可能@Resource标红,导入java的jar包即可

使用@Service将UserServiceImpl标识为Bean,相当于<bean id="userService" class="com.ssm.annotation.UserServiceImpl"/>
然后使用@Resource注解标注在属性UserDao上,相当于<property name="userDao" ref="userDao"/>
最后在该类的save方法中调用UserDao中的save方法,并输出一句话。

  1. 创建控制器UserController
package com.ssm.annotation;

import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

//使用@Controller注解将UserController标识为Bean
@Controller("UserController")
public class UserController {
    //使用@Resource注解注入
    @Resource(name="userService")
    private UserService userService;
    public void save(){
        this.userService.save();
        System.out.println("运行userController.save()");
    }
}

首先使用@Controller注解标注了UserController类,相当于<bean id="userController" class="com.ssm.annotation.UserController"/>
然后使用@Resource注解标注在UserService属性上,相当于<property name="userService" ref="userService"/>
最后在save()方法中调动UserService中的save()方法,并输出一句话

  1. 创建配置文件beans1.xml,在配置文件中编写基于Annotation装配的代码
<?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 
">
<!--    使用context命名空间在配置文件中开启相应的注解处理器-->
    <context:annotation-config/>
<!--        分别定义3个Bean实例-->
    <bean id="userDao" class="com.ssm.annotation.UserDaoImpl"/>
    <bean id="userService" class="com.ssm.annotation.UserServiceImpl"/>
    <bean id="userController" class="com.ssm.annotation.UserController"/>
</beans>

  • 包含了context的约束信息
  • 通过配置开启注解处理器
  • 分别定义了3个实例
  • 不再需要配置子元素< property>

上述注解方式虽然较大程度简化了XML文件的Bean配置,但仍需在Spring文件中配置相应的Bean,为此Spring注解提供了另一种高效的注解配置方式
<context:componet- scan base-package="Bean所在的包路径"/>
则3个实例可进行替换

<?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
">
<!--    使用context命名空间通知Spring扫描指定包下所有的bean类,进行注解解析-->
    <context:component-scan base-package="com.ssm.annotation"/>
</beans>

  1. 创建测试类,编写测试方法并定义配置文件的路径,然后通过Spring容器加载配置文件并获取UserController实例,最后调用save方法。
package com.ssm.annotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AnnotationAssembleTest {
    private static ApplicationContext applicationContext;
    public static void main(String[] args){
        //定义配置文件路径
        String xmlPath="com/ssm/annotation/beans1.xml";
        applicationContext=new ClassPathXmlApplicationContext(xmlPath);
        //获取UserController实例
        UserController userController= (UserController) applicationContext.getBean("UserController");
        //调用UserController中的save方法
        userController.save();
    }
}

  1. 运行结果:
    在这里插入图片描述

这里报错是因为beansl.xml中有错误,schemaLocation中再加一行http://www.springframework.org/schema/context/spring-context.xsd

2.3.3 自动装配

Spring的< bean>元素包含一个autowire属性,我们可以通过设置autowire属性来自动装配Bean。
所谓自动装配,就是将一个Bean自动注入其他Bean的Property中。
autowire属性值


示例2-4

  1. 修改UserServiceImpl.java和UserController.java,增加setter()方法
  2. 修改beans1.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
">
<!--    使用bean元素的autowire属性完成自动装配-->
    <bean id="userDao" class="com.ssm.annotation.UserDaoImpl"/>
    <bean id="userService" class="com.ssm.annotation.UserServiceImpl" autowire="byName"/>
    <bean id="userController" class="com.ssm.annotation.UserController"autowire="byName"/>
</beans>

运行后结果一致

发布了22 篇原创文章 · 获赞 1 · 访问量 861

猜你喜欢

转载自blog.csdn.net/weixin_43651049/article/details/103942898
今日推荐