ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring IoC容器与Bean管理

2021-10-23 20:02:30  阅读:150  来源: 互联网

标签:Apple Spring class Bean context IoC public String


Spring 初识

IoC控制反转

  • IoC控制反转,全称Inverse of Control,是一种设计理念
  • 由代理人创建与管理对象,消费者通过代理人来获得对象
  • IoC的目的是降低程序与程序之间直接耦合

解决什么问题?

对象直接饮用导致对象硬性关联,程序难以扩展。比如:顾客想要吃各种各样的苹果,就需要顾客取世界各地购买苹果,非常麻烦。

加入Ioc容器将对象统一管理,让对象关联变为弱耦合。就像上面的场景:如果出现了摊贩,那么顾客就不用跑到各地去买水果了,而是由摊贩购买好之后,顾客根据自己的需求购买响应的苹果。

 DI依赖注入

  • IoC是设计理念,是现代程序设计遵循的标准,是宏伟目标
  • DI(Dependency Injection) 是具体技术实现,是微观实现
  • DI在Java中利用反射技术是心啊对象注入(Injection)

Spring

含义 

  • Spring可以从狭义与广义两个角度看
  • 狭义角度的Spring是指Spring框架(Spring Fremework)
  • 广义角度Spring是指Spring生态体系

狭义的Spring框架

  • Spring框架是企业开发复杂性的恶一站式解决方案
  • SPring框架的核心是IoC容器与AOP面向切面编程
  • Spring IoC负责创建与管理系统对象,并在此基础上扩展功能

广义Spring生态体系

Spring IoC容器

IoC容器是Spring生态的地基,用于统一创建与管理对象依赖

 如上:Spring IoC容器将A的依赖B对象注入进来,使用者只需要从中提取就可以了。

Spring IoC容器职责

  • 对象的控制权交由第三方统一管理(IoC控制反转)
  • 利用Java反射技术实现运行时对象创建与关联(DI依赖注入)
  • 基于配置提高应用程序的可维护性与扩展性

Spring IoC初体验

eg: 比如三个孩子 Lily、Andy、Luna分别喜欢吃甜的、酸的、软的苹果。盘子里有三个苹果:红富士、青苹果、金帅。

那孩子们如何获得喜欢的苹果呢?

Apple.class

package com.imooc.spring.ioc.entity;

public class Apple {
    private String title;
    private String color;
    private String origin;

    public Apple() {
        //System.out.println("Apple对象已经创建, " + this);
    }

    public Apple(String title, String color, String origin) {
        this.title = title;
        this.color = color;
        this.origin = origin;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getOrigin() {
        return origin;
    }

    public void setOrigin(String origin) {
        this.origin = origin;
    }
}

Child.class

package com.imooc.spring.ioc.entity;

public class Child {
    private String name;
    private Apple apple;

    public Child() {

    }

    public Child(String name, Apple apple) {
        this.name = name;
        this.apple = apple;
    }

    public String getName() {
        return name;
    }

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

    public Apple getApple() {
        return apple;
    }

    public void setApple(Apple apple) {
        this.apple = apple;
    }

    public void eat() {
        System.out.println(name + "吃到了" + apple.getOrigin() + "种植的" + apple.getTitle());
    }
}

传统方式

Application.class

public class Application {
    public static void main(String[] args) {
        Apple apple1 = new Apple("红富士", "红色", "欧洲");
        Apple apple2 = new Apple("青苹果", "绿色", "中亚");
        Apple apple3 = new Apple("金帅", "黄色", "中国");

        Child lily = new Child("莉莉", apple1);
        Child andy = new Child("安迪", apple2);
        Child luna = new Child("露娜", apple3);

        lily.eat();
        andy.eat();
        luna.eat();

    }
}

输出结果:

但是这样会有一个弊端,如果后面需要更改喜欢的苹果的时候,我们就需要在源代码这里修改。在开发过程中,往往源代码涉及到的内容较多,修改复杂且容易影响其他地方,很容易出错。

使用IoC容器方式:

在resources目录下创建applicationontext.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 在IoC容器启动时,自动由Spring实例化Apple对象,取名sweetApple放入到容器中 -->
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="红富士"></property>
        <property name="origin" value="欧洲"></property>
        <property name="color" value="红色"></property>
    </bean>

    <bean id="sourApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="青苹果"></property>
        <property name="origin" value="中亚"></property>
        <property name="color" value="绿色"></property>
    </bean>

    <bean id="softApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="金帅"></property>
        <property name="origin" value="中国"></property>
        <property name="color" value="黄色"></property>
    </bean>

    <bean id="rdApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="蛇果"></property>
        <property name="origin" value="美国"></property>
        <property name="color" value="红色"></property>
    </bean>

    <bean id="lily" class="com.imooc.spring.ioc.entity.Child">
        <property name="name" value="莉莉"/>
        <property name="apple" ref="softApple"/>
    </bean>

    <bean id="andy" class="com.imooc.spring.ioc.entity.Child">
        <property name="name" value="安迪"/>
        <property name="apple" ref="rdApple"/>
    </bean>

    <bean id="luna" class="com.imooc.spring.ioc.entity.Child">
        <property name="name" value="露娜"/>
        <property name="apple" ref="sweetApple"/>
    </bean>
</beans>

SpringApplication.class

public class SpringApplication {
    public static void main(String[] args) {
        //创建Spring IoC容器,并根据配置文件在容器中实例化对象
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Apple sweetApple = context.getBean("sweetApple", Apple.class);
        System.out.println(sweetApple.getTitle());
        //从IoC容器中提取beanId=lily的对象
        Child lily = context.getBean("lily", Child.class);
        lily.eat();
        Child andy = context.getBean("andy", Child.class);
        andy.eat();
        Child luna = context.getBean("luna", Child.class);
        luna.eat();

    }
}

执行结果:

这样做的好处是,我们涉及到修改时,只需要修改applicationContent.xml中的内容即可.

 使用XML方式实现Spring IoC

 上面说的applicationContext.xml就是使用xml文件方式实现Spring IoC的一种。

实现方式:

  1. 基于构造方法对对象实例化
  2. 基于动态工厂实例化
  3. 基于工厂实例方法实例化

Spring框架组成模块

 ApplicationContext实现类

  • ClassPathXmlApplicationContext
  • AnnotationConfigApplicationContext
  • WebApplicationContext

基于构造方法对对象实例化

默认构造方法

在 applicationContext.xml文件:

<!--bean标签默认通过默认构造方法创建对象-->
    <bean id="apple1" class="com.imooc.spring.ioc.entity.Apple">

Apple.class 中修改为:

public Apple() {
        System.out.println("Apple对象已创建," + this);
    }

打印输出:

带参构造方法

applicationContext.xml

<!--使用带参构造方法实例化对象-->
    <bean name="apple2" class="com.imooc.spring.ioc.entity.Apple">
        <constructor-arg name="title" value="红富士"/>
        <constructor-arg name="color" value="红色"/>
        <constructor-arg name="origin" value="欧洲"/>
        <constructor-arg name="price" value="19.8"/>
    </bean>

    <bean id="apple3" class="com.imooc.spring.ioc.entity.Apple">
        <constructor-arg index="0" value="红富士"/>
        <constructor-arg index="1" value="欧洲"/>
        <constructor-arg index="2" value="红色"/>
        <constructor-arg index="3" value="19.8"/>
    </bean>

 Apple.class

public Apple(String title, String origin, String color, Float price) {
        System.out.println("通过带参构造方法创建对象, " + this);
        this.title = title;
        this.color = color;
        this.origin = origin;
        this.price = price;
    }

打印输出:

基于工厂实例化对象

静态工厂

/**
 * 静态工厂通过静态方法创建对象,隐藏创建对象的细节
 */
public class AppleStaticFactory {
    public static Apple createSweetApple(){
        //logger.info("")
        Apple apple = new Apple();
        apple.setTitle("红富士");
        apple.setOrigin("欧洲");
        apple.setColor("红色");
        return apple;
    }
}

在applicationContext.xml中

<!--利用静态工厂获取对象-->
    <bean id="apple4" class="com.imooc.spring.ioc.factory.AppleStaticFactory"
          factory-method="createSweetApple"/>

测试:

 Apple apple4 = context.getBean("apple4", Apple.class);
        System.out.println(apple4.getTitle());

 输出:

工厂实例

/**
 * 工厂实例方法创建对象是指IoC容器对工厂类进行实例化并调用对应的实例方法创建对象的过程
 */
public class AppleFactoryInstance {
    public Apple createSweetApple(){
        Apple apple = new Apple();
        apple.setTitle("红富士");
        apple.setOrigin("欧洲");
        apple.setColor("红色");
        return apple;
    }
}

在applicationContext.xml中

 <!--利用工厂实例方法获取对象-->
    <bean id="factoryInstance" class="com.imooc.spring.ioc.factory.AppleFactoryInstance"/>
    <bean id="apple5" factory-bean="factoryInstance" factory-method="createSweetApple"/>

然后测试输出即可.

从IoC容器中提取 Bean

方式一:
Apple apple = context.getBean("apple", Apple.class);

方式二:
Apple apple = (Apple)context.getBean("apple");

推荐使用方式一

id和name属性相同点

  • bean id 与 name 都是设置对象在IoC容器中唯一标识
  • 两者在同一个配置文件中都不允许出现重复
  • 两者允许在多个配置文件中出现重复,新对象覆盖旧对象

id和name属性不同点

  • id要求更为严格,一次只能定义一个对象标识(推荐)
  • name更为宽松,一次允许定义多个对象标识
  • tips:id与name的命名要求有意义,按驼峰命名书写
<bean name="apple2,apple7" class="com.imooc.spring.ioc.entity.Apple">
        <constructor-arg name="title" value="红富士2号"/>
        <constructor-arg name="color" value="红色"/>
        <constructor-arg name="origin" value="欧洲"/>
        <constructor-arg name="price" value="29.8"/>
    </bean>
    <!-- 没有id与name的bean默认使用类名全称作为bean标识 -->
    <bean class="com.imooc.spring.ioc.entity.Apple">
        <constructor-arg name="title" value="红富士3号"/>
        <constructor-arg name="color" value="红色"/>
        <constructor-arg name="origin" value="欧洲"/>
        <constructor-arg name="price" value="29.8"/>
    </bean>

路径匹配表达式

 ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

 加载多个配置文件:

String[] configLocations = new String[]{"classpath:applicationContext.xml","classpath:applicationContext-1.xml"};
        //初始化IoC容器并实例化对象
       ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);

路径表达式

 对象依赖注入

依赖注入是指运行时将容器内对象利用反射赋给其他对象的操作

  •  基于setter方法注入对象
  • 基于构造方法注入对象

基于setter方法注入对象

<property name="" value=""/> : 静态属性

<property name=""ref=""/> : 动态属性

<bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <!-- IoC容器自动利用反射机制运行时调用setXXX方法为属性赋值 -->
        <property name="title" value="红富士"/>
        <property name="color" value="红色"/>
        <property name="origin" value="欧洲"/>
        <property name="price" value="19.8"/>
    </bean>

    <bean id="lily" class="com.imooc.spring.ioc.entity.Child">
        <property name="name" value="莉莉"/>
        <!-- 利用ref注入依赖对象 -->
        <property name="apple" ref="sweetApple"/>
    </bean>

依赖注入的优势

举例:

applicationContext-dao.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bookDao" class="com.imooc.spring.ioc.bookshop.dao.BookDaoOracleImpl">

    </bean>
</beans>

applicationContext-serice.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bookService" class="com.imooc.spring.ioc.bookshop.service.BookService">
        <!--id=bookDao-->
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>

BookDao

public interface BookDao {
    public void insert();
}

BookDaoImpl

public class BookDaoImpl implements BookDao {
    public void insert() {
        System.out.println("向MySQL Book表插入一条数据");
    }
}

BookService

public class BookService {
    private BookDao bookDao ;
    public void purchase(){
        System.out.println("正在执行图书采购业务方法");
        bookDao.insert();
    }

    public BookDao getBookDao() {
        return bookDao;
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

BookShopApplication

public class BookShopApplication {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-*.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        bookService.purchase();
    }
}

输出:

优点: 比如数据库由MySQL迁移到Oracle.这时候只需要将BookDao这个Bean的class更改为Oracle即可.

注入集合对象

 注入List

注入set

 

注入map 

注入Properties 

 Properties中的key和value只能是String类型

查看容器内对象 

//获取容器内所有beanId数组
        String[] beanNames = context.getBeanDefinitionNames();

for (String beanName:beanNames){
            System.out.println(beanName);
            System.out.println("类型:" + context.getBean(beanName).getClass().getName());
            System.out.println("内容:" + context.getBean(beanName));
        }
 Computer computer = context.getBean("com.imooc.spring.ioc.entity.Computer", Computer.class);

当有多个相同类的Bean时:

 <bean class="com.imooc.spring.ioc.entity.Computer">
        <constructor-arg name="brand" value="微星"/>
        <constructor-arg name="type" value="台式机"/>
        <constructor-arg name="sn" value="8389280012"/>
        <constructor-arg name="price" value="3000"/>
    </bean>

    <bean class="com.imooc.spring.ioc.entity.Computer">
        <constructor-arg name="brand" value="华硕"/>
        <constructor-arg name="type" value="笔记本"/>
        <constructor-arg name="sn" value="9089380012"/>
        <constructor-arg name="price" value="6000"/>
    </bean>
Computer computer1 = context.getBean("com.imooc.spring.ioc.entity.Computer#0", Computer.class);
Computer computer1 = context.getBean("com.imooc.spring.ioc.entity.Computer#1", Computer.class);

Bean对像的作用域及生命周期

bean scope属性

  • bean scope属性用于决定对象何时被创建与作用范围
  • bean scope配置将影响容器内对象的数量
  • 默认情况下bean会在IoC容器创建后自动实例化,全局唯一

scope用法

bean scope属性清单

 singleton的线程安全问题

 

singleton在容器是单例多线程执行,存在线程安全风险 

在单线程下:

当在多线程中:在A用户操作了a.setNum(1)之后,在另一个线程,B用户操了a.setNum(2) .这个时候,A用户打印a.num 就会出现 2,和A用户设置值不同.

prototype多例 

prototype在容器中多实例,占用更多资源,不存在线程安全问题 

singleton和prototype对比

bean生命周期

 

细节调整

  •  prototype使对象创建与init_method延迟至执行业务
  • prototype使对象不再受IoC容器管理,不再触发destroy-method
  • 延迟加载lazy-init属性可让对象创建与初始化延迟到执行代码阶段

生命周期在实战中的应用

singleton和prototype的初始化

singleton的初始化:

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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userDao" class="com.imooc.spring.ioc.dao.UserDao"/>

    
</beans>

在SpringApplication中添加:

public class SpringApplication {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
     
    }
}

打印输出:

也就是说在IoC容器初始化的时候,为我们创建了bean. 

prototype初始化:

 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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userDao" class="com.imooc.spring.ioc.dao.UserDao" scope="prototype"/>

    
</beans>

然后在SpringApplication中测试:

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        System.out.println("======IoC容器已初始化=======");
       UserDao userDao1 = context.getBean("userDao", UserDao.class);
}

输出为:

也就是说,在IoC容器创建的时候,并没有为我们初始化bean对像,而是在我们获取对象的时候,才初始化.singleton模式的初始化顺序跟书写顺序一致。

下面会初始化两个bean对象.

<bean id="userDao" class="com.imooc.spring.ioc.dao.UserDao" scope="prototype"/>

    <bean id="userService" class="com.imooc.spring.ioc.service.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>

在多数情况下,Dao层,server层,control层都是单例的。

实现极简IoC容器

目录结构:

 Apple类

package com.imooc.spring.ioc.entity;

public class Apple {
    private String title;
    private String color;
    private String origin;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getOrigin() {
        return origin;
    }

    public void setOrigin(String origin) {
        this.origin = origin;
    }
}

 然后在applicationContext.xml中添加bean的信息:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="红富士"/>
        <property name="color" value="红色"/>
        <property name="origin" value="欧洲"/>
    </bean>
</beans>

自定义记载配置文件的方法:

接口:ApplicationContext

package com.imooc.spring.ioc.context;

public interface ApplicationContext {
    public Object getBean(String beanId);
}

实现类ClassPathXmlApplicationContext 

public class ClassPathXmlApplicationContext implements ApplicationContext {
    private Map iocContainer = new HashMap();

    /**
     * 读取配置文件
     */
    public ClassPathXmlApplicationContext() {
        try {
            String filePath = this.getClass().getResource("/applicationContext.xml").getPath();
            // 进行URL解码
            filePath = new URLDecoder().decode(filePath, "UTF-8");

            /**
             * 引入 dom4j和jaxen
             * Dom4j是Java的XML解析组件
             * Jaxen是Xpath表达式解释器
             */
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File(filePath));
            // 读取 "bean" 标签
            List<Node> beans = document.getRootElement().selectNodes("bean");

            for (Node node : beans) {
                Element ele = (Element) node;

                String id = ele.attributeValue("id");
                String className = ele.attributeValue("class");

                Class c = Class.forName(className);
                Object obj = c.newInstance();

                List<Node> properties = ele.selectNodes("property");
                for (Node p : properties) {
                    Element property = (Element) p;
                    String propName = property.attributeValue("name");
                    String propValue = property.attributeValue("value");

                    // set方法
                    String setMethodName = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
                    System.out.println("准备执行" + setMethodName + "方法注入数据");
                    Method setMethod = c.getMethod(setMethodName, String.class);
                    setMethod.invoke(obj, propValue);//通过setter方法注入数据
                }
                iocContainer.put(id, obj);
            }
            System.out.println(iocContainer);
            System.out.println("IOC容器初始化完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Object getBean(String beanId) {
        return iocContainer.get(beanId);
    }
}

然后进行测试:

public class Application {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext();
        Apple apple = (Apple)context.getBean("sweetApple");
        System.out.println(apple);
    }
}

执行结果:

 

 

使用注解方式实现Spring IoC

基于注解的优势

  • 摆脱繁琐的XML形式的bean与依赖注入配置
  • 基于“声明式”的原则,更适合轻量级的现代企业应用
  • 让代码可读性变得更好,研发人员拥有更好的开发体验

三类注解:

  1. 组件类型注解 - 声明当前类的功能与职能
  2. 自动装配注解 - 根据属性特种自动注入对象
  3. 元数据注解 - 更细化的辅助IoC容器管理对象的注解

四种组件类型注解

  1. @Compponent  : 组件注解,通用注解,被该注解描述的类将被IoC容器管理并实例化
  2. @Controller  : 语义注解,说明当前类是MVC应用中的控制器类
  3. @Service. : 语义注解,说明当前类是Service业务服务类
  4. @Repository. : 语义注解,说明当前类是用于业务持久层,通常描述对应Dao类

  

两类自动装配注解

  1. 按类型装配
    1. @Autowired : 按容器内对象类型动态注入属性,由Spring机构提供
    2. @Inject : 基于JSR-330(Dependency Injection for Java)标准,其他同@Autowired,但不支持required属性
  2. 按名称装配
    1. @Named : 与@Inject配合使用,JSR-330规范,按属性名自动装配属性
    2. @Resource :基于JSR-330规范,优先按名称、再按类型智能匹配

元数据注解

@Value 的读取属性文件

@Value("com.imooc")
private String config;

就是相当于在初始化的时候,config的值为"com.inooc",主要用户加载配置文件中的数据: @Value("${config}")

使用Java Config方式实现Spring IoC

基于Java Config的优势

  • 完全摆脱XML的束缚,使用独立Java类管理对象与依赖
  • 注解配置相对分散,利用Java Config可对配置集中管理
  • 可以在编译时进行依赖检查,不容易出错

Java Config核心注解

Java Config初始化方式

 

 举例:

package com.imooc.spring.ioc;

import com.imooc.spring.ioc.controller.UserController;
import com.imooc.spring.ioc.dao.EmployeeDao;
import com.imooc.spring.ioc.dao.UserDao;
import com.imooc.spring.ioc.service.UserService;
import org.springframework.context.annotation.*;

@Configuration //当前类是一个配置类,用于替代applicationContext.xml
@ComponentScan(basePackages = "com.imooc")
public class Config {
    @Bean //Java Config利用方法创建对象,将方法返回对象放入容器,beanId=方法名
    public UserDao userDao(){
        UserDao userDao = new UserDao();
        System.out.println("已创建" + userDao);
        return userDao;
    }

    @Bean //Java Config利用方法创建对象,将方法返回对象放入容器,beanId=方法名
    @Primary
    public UserDao userDao1(){
        UserDao userDao = new UserDao();
        System.out.println("已创建" + userDao);
        return userDao;
    }

    @Bean
    //先按name尝试注入,name不存在则按类型注入
    public UserService userService(UserDao udao , EmployeeDao employeeDao){
        UserService userService = new UserService();
        System.out.println("已创建" + userService);
        userService.setUserDao(udao);
        System.out.println("调用setUserDao:" + udao);
        userService.setEmployeeDao(employeeDao);
        return userService;
    }

    @Bean //<bean id="xxx" clas="xxx">
    @Scope("prototype")
    public UserController userController(UserService userService){
        UserController userController = new UserController();
        System.out.println("已创建" + userController);
        userController.setUserService(userService);
        System.out.println("调用setUserService:" + userService);
        return userController;
    }
}

测试:

public class SpringApplication {
    public static void main(String[] args) {
        //基于Java Config配置IoC容器的初始化
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        System.out.println("=========================");
        String[] ids = context.getBeanDefinitionNames();
        for(String id : ids){
            System.out.println(id + ":" + context.getBean(id));
        }
    }
}

 

标签:Apple,Spring,class,Bean,context,IoC,public,String
来源: https://blog.csdn.net/song_hai_lei/article/details/120856434

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有