Day21 Spring入门 SpringIOC

Spring的介绍

  • (1)Spring是什么?
    Spring 是分层的 Java SE/EE 应用
    full-stack 如Web、Service、Dao各层能够无缝地集成在一起
    轻量级 可以按需添加模块
    开源 可以获取源代码
    以 IOC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。
  • (2)有什么特点?
    提供了展现层 SpringMVC
    持久层 Spring JDBC,但还是使用MyBatis
    还能整合开源世界众多著名的第三方框架和类库
    业务层事务管理 AOP
    方便解耦,简化开发 IOC
    Java源码是经典学习范例
    逐渐成为使用最多的 Java EE 企业应用开源框架

Spring架构体系

  • (1)Test :用于测试使用
  • (2)Core container:核心容器,就是用于装Java Bean对象
  • (3)AOP:切面编程
  • (4)Aspects:提供了与AspectJ的集成
  • (5)Data access:数据访问。用于访问操作我们的数据库。支持持久层的操作。jdbcTemplate mybatis
  • (6)Web:用于支持数据展示层,支持http请求
  • (7)Transactions:用于支持事物处理。用于解决业务层的事物处理问题。 编程式事务管理和声明式事务管理.
    在这里插入图片描述

Spring的IOC理论***

  • (1)什么是IOC
    控制反转- (Inversion of Control,缩写为IoC)
    》把原来new对象的这种方式转换成了,spring通过反射创建对象的方式
    》spring创建完的对象放到一个容器中,谁需要就给谁注入进去- (获取对象并赋值给引用)
    简单说:把创建对象和管理对象的权利交给spring

Spring的IOC入门-环境搭建

  • (1)创建Project(maven项目)
  • (2)创建模块module(maven项目)
  • (3)配置依赖
<!--spring依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.9.RELEASE</version>
        </dependency>

Spring的IOC入门-代码编写

  • (1)定义Person类
public class Person {
    
    
	private int id;
    private String name;
    private int age;
    private Date birthday;
    //省略getset和构造
}    
  • (2)手动完成创建与赋值(耦合度太高,不推荐)
  • (3)由spring创建与赋值
    》创建容器对象
    》读配置文件
    new ClassPathXmlApplicationContext(“applicationContext.xml”);
    》从容器中查找 getBean()

首先创建配置文件applicationContext.xml
在这里插入图片描述

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.xsd">

<!--1:在这里添加Spring配置,让Spring自动帮我们创建对象,并且将创建的对象存入IOC容器
    2:Spring会自动扫描当前配置文件红所有的bean标签, 然后回将所有bena标签中配置的类自动创建对象
    3:Spring会将所有创建后的对象存入IOC容器(Spring容器)
 	-->
<!--bean标签的属性
        id:bean标签的识别ID,理论上可以随便写
        class:你要上Spring给你创建哪个类的对象,需要写上该类的全路径名
        内部使用的是反射:全路径名====Class.forName("类全路径名")===无参构造====类对象
    -->
    <bean id="person" class="com.wzx.domain.Person" />
</beans>

Test01SpringIoc

public class Test01SpringIoc {
    
    
  	//成员变量
  	private ClassPathXmlApplicationContext context;
  
	@Before
    public void init(){
    
    
        //1.获取Spring容器对象
        //该方法会自动加载核心配置文件,并自动创建核心配置文件中所有bean标签指定的类对象,并且存入Spring容器
        //方法返回值返回就是Spring容器对象
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
  
    @Test
    public void test01(){
    
    
        //2.从Spring容器中获取对象:调用容器的getBean方法获取id对应的对象
        /* 方式1-不需要强转
           参数1:指定核心配置文件中bean标签的id值
           参数2:指定要获取哪个类的对象
         */
      	Person person1 = context.getBean("person",Person.class);
      	// 方式2-需要强转
        Person person2 = (Person) context.getBean("person");        
    }
}

Spring的IOC入门-静态工厂造对象

  • (1)什么是静态工厂
    有一个静态方法地XxxFactory工厂类
  • (2)通过调用静态方法获取bean对象

创建一个静态工厂类

public class PersonFactory {
    
    
    //工厂类中编写一个静态方法, (返回Person类)
    public static Person getBean() {
    
    
        return new Person();
    }
}

applicationContext.xml

<!--factory-method:指定获取对象的静态工厂的方法-->
<bean class="cn.cyl.demo02.PersonFactory" factory-method="getBean" id="person4"/>

测试

	@Test
    public void test03(){
    
    
        //自己创建
        Person person1 = PersonFactory.getBean();
      
        //xml创建
        Person person2 = (Person) context.getBean("person4");
    }

Spring的IOC入门-实例工厂造对象

  • (1)什么是实例工厂
    XxxFactory
  • (2)通过工厂对象调用成员方法获得bean对象
    XxxFactory factory = new XxxFactory(); //实例化工厂对象
    factory .yyy() //获得对象
  • (3)factory-bean 创建工厂对象
  • (4)factory-method 调用方法获得bean对象

创建一个实例工厂类

public class PersonFactory2 {
    
    
    //方法上没有static,所以必须先new PersonFactory2()才能调用
    public Person getBean(){
    
    
        return new Person();
    }
}

applicationContext.xml

<!--创建实例工厂对象-->
<bean class="cn.cyl.demo03.PersonFactory2" id="factory2"/>
<!--调用工厂里的方法-->
<bean factory-bean="factory2" factory-method="getBean" id="person5"/>

测试

	@Test
    public void test04(){
    
    
        //自己创建
        PersonFactory2 factory2 = new PersonFactory2();
        Person person1 = factory2.getBean();

        //xml创建
        Person person5 = (Person) context.getBean("person5");
    }

Spring的IOC入门-单例和多例

  • 单例是什么?
    内存中只有一个对象,每次获取到该对象的地址值一样.
  • 多实例是什么?
    内存中的每个对象都是一个新的对象,他们的地址值都不同.
  • 简单演示它们的区别

创建单例和多例对象的类

public class MyClass {
    
    
    //单例模式=一个私有的构造方法,一个静态私有的成员变量,还有一个静态的get方法
    private MyClass(){
    
    
        System.out.println("--构造方法MyClass");
    }
    //唯一
    private static MyClass myClass;
    public static MyClass getInstance() {
    
    
        if(myClass == null){
    
    
            myClass=new MyClass();
        }
        return myClass;
    }

    //多实例
    public static MyClass getInstance2() {
    
    
        return new MyClass();
    }
}

测试

//自己创建
    @Test
    public void test05(){
    
    
        //单例
        MyClass myClass1 = MyClass.getInstance();
        MyClass myClass2 = MyClass.getInstance();
        log.debug(myClass1.equals(myClass2)+"");//true

        //多例
        MyClass myClass3 = MyClass.getInstance2();
        MyClass myClass4 = MyClass.getInstance2();
        log.debug(myClass3.equals(myClass4)+"");//false
    }
  • (1)问题: 每次获取对象的时候,spring是新创建一个对象还是始终给我们返回同一个对象.
  • (2)答案: spring默认的情况下创建的对象都是单例的. (每次返回的对象都是同一个)
        scope="singleton" 单例(默认值)
        scope="prototype" 多例
        scope="request" 创建的对象放到request域中
        scope="session" 创建对象放到session对象

单实例

    <bean id="person" class="cn.cyl.domain.Person" scope="singleton"/>

多实例

    <bean id="person" class="cn.cyl.domain.Person" scope="prototype"/>

Spring的IOC入门-Spring生命周期(了解)

  • (1)生命周期
    创建方法init
    销毁方法destory
    普通方法service
  • (2)属性
    init-method 当该对象初始化的时候该方法会自动执行
    destroy-method 当该对象即将销毁的时候会自动调用该方法
  • 示例

实体类

public class Person{
    
    
   public void init(){
    
    
        System.out.println("初始化...");
    }
    public void eat(){
    
    
        System.out.println("普通方法...");
    }
    public void destory(){
    
    
        System.out.println("销毁...");
    }
}

applicationContext.xml

<bean class="cn.cyl.domain.Person" id="person6" init-method="init" destroy-method="destroy"/>

测试

	@Test
    public void  test07(){
    
    
        Person person = (Person) context.getBean("person6");
        person.eat();

        //关闭容器
        context.close();
    }

Spring依赖注入DI-set方法

  • (1)什么是依赖注入
    DI (dependency injection) 依赖注入
    含义:就是给对象的属性设置值.
    set方法给对象设置值
    构造方法给对象初始化的时候设置值.
  • (2)property标签
    set方式设置属性(掌握)
    让spring调set方法,前提条件类中必须有set方法

name : 代表的是set方法去掉set,首字母小写。setName—>Name—>name
value: 基本类型或字符串类型的值,具体给属性设置用的
ref(引用) : 引用对象的id,作为一个对象类型注入

  • 示例

applicationContext.xml

	<!--使用spring创建一个日期-->
    <bean id="c" class="java.util.Date"></bean>
    
	<!--set方法创建对象-->
    <bean id="person2" class="cn.cyl.domain.Person">
        <!--一个property标签最后会调一个对应的set方法
            name:成员变量的名字
            value:成员变量的值,value可以赋上基本类型数据与String,但是其他对象,要使用ref
            ref:指向其他对象-->
        <property name="id" value="10"/>
        <property name="name" value="rose"/>
        <property name="age" value="20"/>
        <property name="birthday" ref="birthday"/>
    </bean>

Spring依赖注入-构造方法

  • (1)通过构造方法给成员变量赋值
  • (2)<constructor-arg>
    前提条件类中必须有有参构造方法
  • 示例
	<!--构造方法创建对象-->
    <bean id="person3" class="cn.cyl.domain.Person">
        <!--constructor-arg 如果有四个,就表示调的一个四个参数的构造方法。实体类没有此构造会报错-->
        <constructor-arg name="id" value="10"/>
        <constructor-arg name="name" value="hello"/>
        <constructor-arg name="age" value="20"/>
        <constructor-arg name="birthday" ref="birthday"/>
    </bean>

Spring依赖注入-给复杂类型注入

  • (1)什么是复杂类型?
    简单的是基本类型与字符串
    Aarry数组,List集合,Map集合,Set集合,Properties集合
  • (2)如何给这些属性设置值
    使用对应的子标签
    array,list,map,set,props
  • 示例

实体类

public class Person{
    
    
//复杂类型
  	//数组
    private String[] arr; 
    public void setArr(String[] arr) {
    
    
        this.arr = arr;
    }
    //List
    private List<String> list;
    public void setList(List<String> list) {
    
    
        this.list = list;
    }
    //set
    private Set<String> set;
    public void setSet(Set<String> set) {
    
    
        this.set = set;
    }
    //map
    private Map<String,String> map;
    public void setMap(Map<String, String> map) {
    
    
        this.map = map;
    }
    //properties
    private Properties properties;
    public void setProperties(Properties properties) {
    
    
        this.properties = properties;
    }
}

applicationContext.xml

<!--    复杂类型注入-->
    <bean id="person7"
          class="cn.cyl.domain.Person">
        <property name="name" value="jack"/>
        <property name="arr">
            <array>
                <value >rose</value>
                <value >rose</value>
                <value >rose</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value >rose1</value>
                <value >rose2</value>
                <value >rose3</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value >rose</value>
                <value >rose</value>
                <value >rose3</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="10010" value="rose1"/>
                <entry key="10086" value="rose2"/>
                <entry key="110" value="rose3"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="10010">rose1</prop>
                <prop key="10086">rose2</prop>
                <prop key="110">rose3</prop>
            </props>
        </property>
    </bean>

猜你喜欢

转载自blog.csdn.net/qq_43639081/article/details/109109774