Spring之(六)Bean的装配方式

六、Bean的装配方式

Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式。

6.1 基于XML的装配

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

  1. Bean类必须提供一个默认的无参构造方法;
  2. Bean类必须为需要注入的属性提供对应的setter方法。

实体类User.java

//实体类User
package com.spring.pojo;
import java.util.List;
public class User {
    private String username;
    private int password;
    private List<String> list;

    /**
     * 1.使用构造注入
     * 提供带有所有参数的有参构造方法
     * @param username
     * @param password
     * @param list
     */
    public User(String username, int password, List<String> list) {
        this.username = username;
        this.password = password;
        this.list = list;
    }

    /**
     * 2.设值注入
     * 2.1 提供默认空参构造函数
     * 2.2 为所有属性提供setter方法
     */
    public User() {
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(int password) {
        this.password = password;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password=" + password +
                ", list=" + list +
                '}';
    }
}

配置文件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-2.5.xsd">
   <!--1.使用构造注入方式装配User实例-->
    <bean id="user1" class="com.spring.pojo.User">
        <constructor-arg index="0" value="tom"/>
        <constructor-arg index="1" value="123456"/>
        <constructor-arg index="2">
            <list>
                <value>"constructorvalue1"</value>
                <value>"constructorvalue2"</value>
            </list>
        </constructor-arg>
    </bean>
    <!--2.使用设置注入方式装配User实例-->
    <bean id="user2" class="com.spring.pojo.User">
        <property name="username" value="张三"/>
        <property name="password" value="654321"/>
        <property name="list">
            <list>
                <value>"setlistvalue1"</value>
                <value>"setlistvalue2"</value>
            </list>
        </property>
    </bean>
</beans>

测试类test.java

package com.spring.test;
import com.spring.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
    public static void main(String[] args) {
        //加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/spring/applicationContext.xml");
        User user1 = (User) applicationContext.getBean("user1");
        User user2 = (User) applicationContext.getBean("user2");
        //构造当时输出结果
        System.out.println(user1);
        System.out.println(user2);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.2 基于Annotation(注解)的装配

在Spring中,尽管使用xml配置文件可以实现Bean的装配工作,但如果应用中有很多Bean时,会导致xml配置文件过于臃肿,给后续的维护和升级工作带来一定的困难。因此,Spring提供了对Annotation(注解)技术的全面支持。
Spring中常用的注解:

注解名称注解描述
@Component描述Spring中的Bean,是一个泛华的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次,使用时只需将该注解标注在相应类上即可。
@Repository用于将数据访问层(Dao层)的类标识为Spring中的Bean,其功能与@Component相同
@Service通常作用在业务层(Service层),用于将业务层的类标识为Spring中的Bean,其功能与@Component相同
@Controller通常作用在控制层,用于将控制层的类标识为Spring中的Bean,其功能与@Component相同
@Autowired用于对Bean的属性变量、属性的setter方法以及构造方法进行标注,配合对应的注解处理器完成Bean的自动配置工作。默认按照Bean的类型进行装配
@Resource其作用与Autowired一样。其区别在于@Autowired默认按照Bean类型装配,而@Resource默认按照Bean实例名称进行装配。
@Qualifier与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier的参数指定

小贴士:

  1. @Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。如果指定name属性,则按实例名称进行装配;如果指定type属性,则按照Bean类型进行装配;如果都不指定,则先按Bean实例名称装配,如果不能匹配,再按照Bean类型进行装配;如果都无法匹配,则抛出NoSuchBeanDefinitionException异常。
  2. @Component 注解是一个泛华的概念,与@Repository、@Service和@Controller作用相同;
  3. @Qualifier一般和@Autowired 联合使用,其联合效果和@Resource使用效果相同。

数据访问层UserDao.java及其实现类UserDaoImpl.java

//UserDao.java
package com.spring.dao;
public interface UserDao {
    public void save();
}
//UserDaoImpl.java
package com.spring.dao.impl;
import com.spring.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("执行dao层的save方法...");
    }
}

业务层UserService.java及其实现类UserServiceImpl.java

//UserService.java
package com.spring.service;
public interface UserService {
    public void save();
}
//UserServiceImpl.java
package com.spring.service.impl;
import com.spring.dao.UserDao;
import com.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
	@Resource(name="userDao")
    //@Autowired
    UserDao userDao;
    @Override
    public void save() {
        userDao.save();
        System.out.println("执行service层的save方法...");
    }
}

控制层UserController.java

package com.spring.controller;
import com.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller("userController")
public class UserController {
    //@Resource(name="userService")
    //@Autowired
    UserService userService;
    public void save(){
        userService.save();
        System.out.println("userController的save方法执行...");
    }
}

配置文件applicationContext_annotation.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:aop="http://www.springframework.org/schema/aop"
       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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
    <!--开启注解-->
    <context:annotation-config/>
    <!--分别定义3个Bean的实例-->
    <bean id="userDao" class="com.spring.dao.impl.UserDaoImpl"/>
    <bean id="userService" class="com.spring.service.impl.UserServiceImpl"/>
    <bean id="userController" class="com.spring.controller.UserController"/>


    <!--配置注解扫描包--通知Spring扫描指定包下所有的Bean类,进行注解解析(推荐使用)-->
	<context:component-scan base-package="com.spring.*"/>
</beans>

小贴士:

  1. 很明显,实例化3个bean的方式很繁琐,不利于代码的维护,所以我们一般采用配置注解扫描包的方式进行配置!!
  2. 使用@Autowire注解和@Resource注解可以达到同样的效果!!

测试类test.java

package com.spring.test;
import com.spring.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class tset2 {
    public static void main(String[] args) {
        ApplicationContext context = new FileSystemXmlApplicationContext("src/com/spring/applicationContext_annotation.xml");
        UserController userController = (UserController) context.getBean("userController");
        userController.save();
    }
}

6.3 自动装配

Spring的bean元素中包含一个autowire属性,通过设置autowire的属性值来自动装配Bean。所谓自动装配,就是将一个Bean自动地注入到其他Bean的Property中。
autowire属性有5个值:

属性值说明
default(默认值)由bean的上级标签beans的default-autowire属性值确定
byName根据属性的名称自动装配。容器将根据名称查找与属性完全一致的Bean,并将其属性自动装配
byType根据属性的数据类型(Type)自动装配,如果一个Bean的数据类型兼容另一个Bean中属性的数据类型,则自动装配
constructor根据构造函数参数的数据类型进行byType模式的自动装配
no在默认情况下,不使用自动装配,Bean依赖必须通过ref元素定义

分别在UserServiceImpl.java和UserController.java类中添加类的setter方法:

//UserServiceImpl.java
package com.spring.service.impl;
import com.spring.dao.UserDao;
import com.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
    UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        userDao.save();
        System.out.println("执行service层的save方法...");
    }
}
//UserController.java
package com.spring.controller;
import com.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller("userController")
public class UserController {
    UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void save(){
        userService.save();
        System.out.println("userController的save方法执行...");
    }
}

在配置文件中加入autowire属性:

<?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:aop="http://www.springframework.org/schema/aop"
       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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
    <!--开启注解-->
    <context:annotation-config/>
    <!--分别定义3个Bean的实例-->
    <bean id="userDao" class="com.spring.dao.impl.UserDaoImpl"/>
    <bean id="userService" class="com.spring.service.impl.UserServiceImpl" autowire="byName"/>
    <bean id="userController" class="com.spring.controller.UserController" autowire="byName"/>
</beans>
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值