【Spring】IOC从演变到自动装配的全攻略详解(二)

简介: 【Spring】IOC从演变到自动装配的全攻略详解(二)

2.3.依赖注入

2.3.1.Set注入(重点)

userAction.java

public class UserAction {
    private UserService userService;
    private String name;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    public Map<String, String> getCard() {
        return card;
    }
    public void setCard(Map<String, String> card) {
        this.card = card;
    }
    public Set<String> getGames() {
        return games;
    }
    public void setGames(Set<String> games) {
        this.games = games;
    }
    public String[] getBooks() {
        return books;
    }
    public void setBooks(String[] books) {
        this.books = books;
    }
    public List<String> getHobbys() {
        return hobbys;
    }
    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public String Update(){
        userService.update();
        System.out.println("名字:"+name);
        System.out.println("书籍:");
        for (String book:books){
            System.out.print("<<"+book+">>\t\n");
        }
        System.out.println("爱好:"+hobbys);
        System.out.println("card:"+card);
        System.out.println("games:"+games);
        return "list";
    }
}

GoodsAction.java

public class GoodsAction {
    private UserService userService;
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public String Update(){
        userService.update();
        return "list";
    }
}

Test测试类

public class UserTest {
    public static void main(String[] args) {
        //加载spring核心配置文件(建模)获取spring的上下文对象
        //上下文对象中可以获取任何Javabean对象
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/Spring-Context.xml");
        //用户
        UserAction useraction = (UserAction) context.getBean("userAction");
        useraction.Update();
        System.out.println("  ===============================");
        //商品
        GoodsAction goodsAction= (GoodsAction) context.getBean("goodsAction");
        goodsAction.Update();
    }

1.Bean注入

这里的值是一个引用,ref

 <bean class="com.csdn.xw.web.UserAction" id="userAction">
        <property name="userService" ref="serviceImpl2"></property>
        <property name="name" value="小明"></property>
 </bean>
  <bean class="com.csdn.xw.service.impl.UserServiceImpl2" id="serviceImpl2"></bean>

2.数组注入

<property name="books" >
            <array>
                <value>西游记</value>
                <value>红楼梦</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
</property>

3.List注入

 <property name="hobbys">
            <list>
                <value>唱</value>
                <value>跳</value>
                <value>RAP</value>
            </list>
 </property>

4.Map注入

 <property name="card">
            <map>
                <entry key="JAVA" value="100"></entry>
                <entry key="Python" value="100"></entry>
            </map>
 </property>

5.Set注入

 <property name="games">
            <set>
                <value>电脑</value>
                <value>鼠标</value>
            </set>
 </property>

测试结果:

2.3.2.构造注入

无参构造创建对象

userAction.java

public class UserAction {
    public UserAction() {
        System.out.println("user创建了");
    }
}

spring-context.xml

<bean class="com.csdn.xw.web.UserAction" id="UserAction"></bean>

测试结果:

有参构造创建对象

userAction.java

public class UserAction {
    private String name;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    //有参构造器
    public UserAction(String name, String[] books, List<String> hobbys, Map<String, String>                     card, Set<String> games) {
        this.name = name;
        this.books = books;
        this.hobbys = hobbys;
        this.card = card;
        this.games = games;
    }
    /测试有无注入
     public void pros(){
        System.out.println("名字:"+name);
        System.out.println("书籍:");
        for (String book:books){
            System.out.print("<<"+book+">>\t\n");
        }
        System.out.println("爱好:"+hobbys);
        System.out.println("card:"+card);
        System.out.println("games:"+games);
    }
}

spring-context.xml

    <bean class="com.csdn.xw.web.UserAction" id="userAction">
        <property name="userService" ref="serviceImpl2"></property>
        <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="books">
            <array>
                <value>大话数据结构</value>
                <value>大话设计模式</value>
            </array>
        </constructor-arg>
        <constructor-arg name="hobbys">
            <list>
                <value>沐浴</value>
                <value>足疗</value>
                <value>按摩</value>
            </list>
        </constructor-arg>
        <constructor-arg name="card">
            <map>
                <entry key="csdn" value="nb"></entry>
            </map>
        </constructor-arg>
        <constructor-arg name="games">
            <set>
                <value>Java方文山</value>
            </set>
        </constructor-arg>
    </bean>

测试结果:

2.4.自动装配

byName(按名称自动装配)

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。采用自动装配将避免这些错误,并且使配置简单化。

测试:

1、修改bean配置,增加一个属性 autowire=“byName”

 <bean class="com.csdn.xw.web.GoodsAction" id="goodsActiona" autowire="byName">
        <property name="userService" ref="serviceImpl1"></property>
 </bean>
<beans xmlns="http://www.springframework.org/schema/beans"
       default-autowire="byName"
       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">

2、再次测试,结果依旧成功输出!

3、我们将 GoodsAction的bean id修改为 goodsACtion

4、再次测试, 执行时报空指针java.lang.NullPointerException。因为按byName规则找不对应set方法,真正的setgoodsAction就没执行,对象就没有初始化,所以调用时就会报空指针错误。

小结:

当一个bean节点带有 autowire byName的属性时

或是beans节点带有 default-autowire="byName"。

  1. 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
  2. 去spring容器中寻找是否有此字符串名称id的对象。
  3. 如果有,就取出注入;如果没有,就报空指针异常。

byType (按类型自动装配)

使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。

NoUniqueBeanDefinitionException

测试:

1、将user的bean配置修改一下 : autowire=“byType”

2、测试,正常输出

3、在注册一个goodsAction的bean对象!

<bean class="com.csdn.xw.web.GoodsAction" id="goodsAction" autowire="byType">
</bean>
<bean class="com.csdn.xw.web.UserAction" id="userAction" autowire="byType">
        <property name="userService" ref="serviceImpl2"></property>
</bean>
<bean class="com.csdn.xw.service.impl.UserServiceImpl2" id="serviceImpl2"></bean>
<bean class="com.csdn.xw.service.impl.UserServiceImpl1" id="serviceImpl1"></bean>

4、测试,报错:NoUniqueBeanDefinitionException

5、在这个配置中,我们定义了两个UserService的实现类 UserServiceImpl1和 UserServiceImpl2,并且将UserAction的autowire属性设置为byType,表示使用byType进行自动装配。

现在,如果我们运行这个程序,将会抛出一个异常,提示存在多个匹配的 bean,无法确定要注入哪个 bean。这是因为 UserAction类依赖于UserService接口,而容器中存在两个与 UserService接口匹配的 bean,即 UserServiceImpl1和 UserServiceImpl2,导致无法确定要注入哪个 bean。

这就是按照类型自动装配!

2.5.spring与web容器的整合

每一次的请求都需要进行建模,十分消耗新能,希望建模一次,然后每次的请求都可以拿到spring的上下文。使用监听器将spring上下文放入tomcat上下文中。

SpringLoadlistener.java

@WebListener
public class SpringLoadlistener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("初始化将Spring的上下文放入tomcat");
        //将Spring的上下文放入tomcat
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/Spring-Context.xml");
        //获取tomcat上下文
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("springcontext",context);
    }
}

UserServlet.java

@WebServlet("/userlist")
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //处理请求的时候获取spring上下文
        ClassPathXmlApplicationContext springcontext = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springcontext");
        UserAction useraction = (UserAction) springcontext.getBean("userAction");
        System.out.println(useraction);
        useraction.Update();
    }
}

测试结果:

到这里我的分享就结束了,欢迎到评论区探讨交流!!

如果觉得有用的话还请点个赞吧 ♥  ♥


相关文章
|
18天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
9天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
21 0
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
126 9
|
1月前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
28 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
2月前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
40 4
|
30天前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
65 0
|
1月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
45 0
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
5月前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
46 1
|
2月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
210 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)