Spring IoC

Spring IoC,第1张

Spring IoC

Spring Ioc是Spring公司对“控制反转”思想的实现,运用xml来管理和创建bean

三种XML管理、创建bean的方式:

    基于构造方法实例对象

    基于静态工厂实例化对象。

    基于工厂实例方法实例化对象。

实体类

package pers.thc.spring.IoC.entity;

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

    public Apple(){}
    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;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "title='" + title + ''' +
                ", color='" + color + ''' +
                ", origin='" + origin + ''' +
                '}';
    }
}
package pers.thc.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;
    }

    @Override
    public String toString() {
        return "Child{" +
                "name='" + name + ''' +
                ", 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;
    }
}

静态工厂类

package pers.thc.spring.IoC.factory;

import pers.thc.spring.IoC.entity.Apple;

public class AppleFactory {
    public static Apple createSweetApple(){
        Apple apple = new Apple("红富士", "深红", "欧洲");
        return apple;
    }
}

实例工厂类

package pers.thc.spring.IoC.factory;

import pers.thc.spring.IoC.entity.Apple;

public class AppleFactoryInstance {
    public Apple createSweetApple(){
        Apple apple = new Apple("红富士", "深红", "欧洲");
        return apple;
    }
}

applicationContext.xml



    
        
        
        
    
    
        
        
        
    
    
        
        
        
    
    
        
        
        
    
    
        
        
    
    
        
        
        
    
    
        
        
        
    
    
    
    
    
    


    
        
        
        
    
Application类
package pers.thc.spring.IoC;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import pers.thc.spring.IoC.entity.Apple;
import pers.thc.spring.IoC.entity.Child;

public class SpringApplication {
    public static void main(String[] args) {
        String configLocations[]=new String[]{
            "classpath:applicationContext.xml", "classpath:applicationContext1.xml"};
        //应用上下文加载顺序与字符串先后顺序有关
        //启动IoC容器
//        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
        //利用getBean来获取相应的实例对象
//        Apple sweetApple = (Apple)context.getBean("sweetApple");
        Apple sweetApple = context.getBean("sweetApple", Apple.class);//由于sweetApple在两个配置文件中都有,故后加载的配置文件中的sweetApple会覆盖掉先加载配置文件中的sweetApple

        Child Lily = context.getBean("Lily", Child.class);
        Child lily = context.getBean("lily", Child.class);//通过name标签可以设置多个bean标识,此处用lily标识获取实例对象

        Apple apple = context.getBean("pers.thc.spring.IoC.entity.Apple", Apple.class);//若bean没有id、name标签,则通过完整类名获取实例对象

        Apple apple1 = context.getBean("apple1", Apple.class);
        Apple apple2 = context.getBean("apple2", Apple.class);
        Apple apple3 = context.getBean("apple3", Apple.class);
        Apple apple4 = context.getBean("apple4", Apple.class);

        System.out.println(sweetApple);
        System.out.println(Lily);
        System.out.println(lily);
        System.out.println(apple);
        System.out.println(apple1);
        System.out.println(apple2);
        System.out.println(apple3);
        System.out.println(apple4);

    }
}
路径表达式:

    classpath:config.xml 扫描classpath根路径(不包含jar)的config.xml

    classpath:pers/thc/config.xml 扫描classpath下(不包含jar)pers.thc包中的config.xml

    classpath*:pers/thc/config.xml 扫描classpath下(包含jar)pers.thc包中的config.xml

    classpath:config-*.xml 扫描classpath根路径下所有一config-开头的XML文件

    classpath:persconfig.xml 扫描pers包下(包含任何子包)的config.xml file:c/:config.xml 扫描c盘根路径config.xml

两种对象依赖注入方式:

    setter注入对象(property)

    构造方法注入对象(constructor-arg)

IoC模拟团队分工:

        bookshop 利用不同的配置文件,约定好bean的id,建立依赖关系(service的parent context为dao),实现分工合作。 其次,利用IoC容器还可以实现对象之间的解耦,当dao层修改实现细节时,秩序保证bean的id不变,service层不需要进行任何改变。

注入集合对象:

        通过“公司资产配置清单”案例学习集合类型动态注入

公司实体类

package pers.thc.spring.IoC.companyProperties.entity;

import java.util.List;
import java.util.Map;
import java.util.Properties;

public class Company {
    private List rooms;
    private Map computers;
    private Properties info;

    @Override
    public String toString() {
        return "Company{" +
                "rooms=" + rooms +
                ", computers=" + computers +
                ", info=" + info +
                '}';
    }

    public List getRooms() {
        return rooms;
    }

    public void setRooms(List rooms) {
        this.rooms = rooms;
    }

    public Map getComputers() {
        return computers;
    }

    public void setComputers(Map computers) {
        this.computers = computers;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }
}

电脑实体类

package pers.thc.spring.IoC.companyProperties.entity;

public class Computer {
    private String brand;
    private String type;
    private String sn;
    private Float price;

    public Computer() {
    }

    public Computer(String brand, String type, String sn, Float price) {
        this.brand = brand;
        this.type = type;
        this.sn = sn;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "brand='" + brand + ''' +
                ", type='" + type + ''' +
                ", sn='" + sn + ''' +
                ", price=" + price +
                '}';
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getSn() {
        return sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }
}

applicationContext.xml



    
        
        
        
        
    
    
        
        
        
        
    
    
        
        
        
        
    
    
        
            
                2001-总裁办
                2003-总经理办公室
                2010-研发部会议室
            
        
        
            
                
                
                    
                        
                        
                        
                        
                    
                
                
                    
                        
                        
                        
                        
                    
                
            
        
        
            
                0772-3626316
                广西省柳州市城中区八一路XX路XX栋XXXX室
                http://www.xxx.com
            
        
    

Application类

package pers.thc.spring.IoC.companyProperties;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import pers.thc.spring.IoC.companyProperties.entity.Company;
import pers.thc.spring.IoC.companyProperties.entity.Computer;

public class CompanyPropertiesApplication {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-company-properties.xml");
        Company company = context.getBean("company", Company.class);
        System.out.println(company);
        //获取容器内所有beanId数组
        String[] names = context.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        Computer computer = context.getBean("pers.thc.spring.IoC.companyProperties.entity.Computer#1", Computer.class);
        System.out.println(computer);//获取匿名bean的方法-2,通过类名全称#序号来获取相应的bean对象。序号为0,1,2……,按applicationContext.xml中的顺序递推
    }
}
bean scope属性:

    bean scope属性用于决定对象何时被创建与作用范围

    bean scope配置将影响容器内对象的数量

    默认情况下bean会在IoC容器创建后自动实例化,全局唯一

bean scope属性清单:

    singleton 单例(默认值),每一个容器有且只有唯一的实例,实例会被全局共享。单例多线程,但存在线程安全风险。 singleton线程安全问题,a=2(用户1)a.setNum(1)->a对象num=1,(用户2)sout(a.getNum())->本应输出2,现输出1

    prototype 多例,每次使用时都会创建一个实例

    request web环境下,每一次独立请求存在唯一实例

    session web环境下,每一次session存在有唯一实例

    global session portlet的web应用的共享session中

    websocket 每一次websocket连接中存在唯一实例

singleton(左)和prototype(右)对比:

    对象数量:全局唯一 存在多个

    实例化时机:IoC容器启动时 getBean()或对象注入时

    线程安全问题: 存在 不存在

    执行效率:高 低

bean的生命周期:

    容器行为:Ioc容器准备初始化解析XML->为对象注入属性->IoC容器初始化完毕->IoC容器准备销毁

    对象行为:对象实例化执行构造方法->调用init-method初始化方法->执行业务逻辑->调用destroy-method释放资源

Order实体类

package pers.thc.spring.IoC.lifecycle;

public class Order {
    private Float price;
    private Integer quantity;
    private Float total;

    public Order(){
        System.out.println("创建Order对象,"+this);
    }
    public void init(){
        System.out.println("执行init()方法");
        total=price*quantity;
    }
    public void destroy(){
        System.out.println("释放与订单对象相关的资源");
    }
    public void pay(){
        System.out.println("订单金额为:"+total);
    }
    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        System.out.println("设置price:"+price);
        this.price = price;
    }

    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        System.out.println("设置quantity:"+quantity);
        this.quantity = quantity;
    }

    public Float getTotal() {
        return total;
    }

    public void setTotal(Float total) {
        this.total = total;
    }
}

application Context.xml



    
        
        
    

Application类

package pers.thc.spring.IoC.lifecycle;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class LifeCycleApplication {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-lifecycle.xml");
        System.out.println("========IoC容器已初始化========");
        Order order1 = context.getBean("order1", Order.class);
        order1.pay();
        context.registerShutdownHook();//调用destroy-method方法销毁bean实例
    }
}

注解开发: 三类注解

    组件装配注解-声明当前类的功能和职责 四类组件类型注解:

      @Component 组件注解,通用注解,被注解描述的类将被IoC容器管理并实例化

      @Controller 语义注解,MVC控制层

      @Service 语义注解,MVC业务层

      @Repository 语义注解,MVC数据持久化层 开启组件扫描: /context:component-sacn

    自动装配注解-根据属性特征自动注入对象 两类自动装配注解:

      按类型装配:

        @Autowired 按容器内对象类型动态诸如属性,由Spring机构提供

        @Inject 基于JSR-330(Denpendency Inject for java)标准,其他同@Autowired,但不支持required属性

      按名称装配:

        @Named 与@Inject配合使用,JSR-330标准,按属性名自动装配属性

        @Resource 基于JSR-250规范,优先按名称、再按类型智能匹配

    元数据注解-更细化的辅助IoC容器管理对象的注解

      @Primary 按类型装配时出现多个相同类型对象,拥有此注解对象优先被注入

      @PostConstruct 描述方法,相当于XML中init-method配置的注解版本

      @PreDestroy 描述方法,相当于XML中destroy-method配置的注解版本

      @Scope 设置对象的scope属性

      @Value 为属性注入静态数据

使用Java Config配置IoC容器: Java Config核心注解

    @Configuration 描述类,说明当前类时Java Config配置类,完全替代XML文件

    @Bean 描述方法,方法返回对象将被IoC容器管理,beanId默认为方法名

    @importResource 描述类,加载静态文件,可以使用@Value注解获取

    @ComponentScan 描述类,同XML的context:component-scan标签

Spring与JUnit4整合

    Maven工程依赖spring-test

    利用@RunWith(让Spring接管JUnit4的控制权)与@ContextConfiguration(初始化过程中加载哪个初始化文件)描述测试用例类

    测试用例类从容器获取对象完成测试用例的执行

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import pers.thc.spring.IoC.springtest.service.UserService;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext-test.xml"})
public class SpringTestor {
    @Resource
    private UserService userService;

    @Test
    public void testUserService(){
        userService.createUser();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5721822.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存