Spring(二)

1.Spring中的IOC[控制反转]

没有Spring之前

public class Student{}

//new+构造函数

Student stu = new Student();

有Spring之后

public  class  Student{}

applicationContext.xml(Spring的核心配置文件)

<bean id="stu" class="com.bean.Student">

ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");

Student stu=ac.getBean("stu",Student.class);

在之前我们编写好的java类在创建对象的时候,都是new+构造方法来完成对象的创建,此时对象创建和维护的权利都控制在开发人员手中。

        IOC[控制反转]: 就是将对象的创建和维护权利从开发人员手中转移到Spring容器。
就是通过Spring容器来创建和维护对象。

IOC[控制反转]是一种思想概念,通过这个思想概念的具体实现操作Spring DI(依赖注入)

2.Spring中的DI[依赖注入]

依赖注入(Dependency Injection,DI)和控制反转含义相同,它们是从两个角度描述的同一个概念。

//被调用者
public  class  Student{
	public  String getStudent(){
		return  "网星";
	}
}

//调用者
public  class  Person{
	private  Student  stu=null;
	public  void  testPerson(){
		stu=new Student();
		System.out.println(stu.getStudent());
	}
}

调用者类【Person】在执行过程中需要使用被调用者【Student】类的对象,此时被调用者【Student】类的对象就是调用者类【Person】的依赖对象----依赖
注入---将依赖对象传递给调用者类【Person】的过程。
依赖注入----将依赖对象传递给调用者类中的过程。
在没有Spring的时候我们通过传递参数的方法将依赖对象传递给调用者类。

有了Spring以后对象创建和维护都是由Spring容器来完成,通过传递参数的方法将依赖对象传递给调用者。所以我们现在只能通过Spring容器来完成依赖注入。

通过Spring的配置文件【applicationContext.xml】完成依赖注入的方式。

1.setter注入:Set方法注入(嵌套property元素)

Student类【被调用者】
public class Student {
    public String getTitle() {
        return "一起来看流星雨";
    }
}


Teacher类【调用者】
public class Teacher {
    private Student param;
    public void testPerson(){
        String str = param.getTitle();
        System.out.println(str);
    }

    public void setParam(Student param) {
        this.param = param;
    }

    public Student getParam() {
        return param;
    }
}

applicationContext.xml【Spring核心配置文件】

<bean id="stu"class="com.bean.Student"></bean>
<bean id="person"class="com.bean.Person">
    <!-- name:实例属性名 
         ref:引用/引入Spring创建的依赖对象    
    -->
    <property name="param" ref="stu">
</bean>

2.构造函数注入(嵌套constructor-arg元素)

Student类(被调用者)

public class Student {
    public String getTitle(){
        return "你好啊,约的惹人";
    }
}


Person类(调用者)
public class Person {
    private Student parm2;

    public Person(Student parm2) {
        this.parm2 = parm2;
    }

    public Student getParm2() {
        return parm2;
    }

    public void setParm2(Student parm2) {
        this.parm2 = parm2;
    }
    public void fageTest(){
        String title = parm2.getTitle();
        System.out.println(title);
    }
}


applicationContext.xml(Spring核心配置文件)
<bean id="stu" class="com.bean.Student"></bean>
<bean id="per" class="com.bean.Person">
    <!--
     name:调用者实例名
     ref:引入/引用Spring的容器依赖对象
     type:构造参数类型
     index:构造函数的参数位置
     -->
    <constructor-arg name="parm2" ref="stu"></constructor-arg>:
</bean>

3.Spring实例化Bean的三种方法

通过Spring配置文件创建java类对象的方式

1)构造器实例化

构造器实例是指Spring容器通过Bean对应的类默认的构造函数实例化

Bean类
public class ConStroctorCreateObjectTest {
    public void getBean(){
        System.out.println("构造器实例化是指Spring容器通过Bean的id属性对应类默认构造实例Bean对象");
    }
}

<bean id="csco" class="com.bean.ConStroctorCreateObjectTest">

2)实例工厂的方法实例化

需要提供一个静态工厂方法创建Bean的实例

被实例的类

public class Student{

    public void testStudent(){
     System.out.println("通过构造工厂创建的实例对象")
    }
}

实例工厂类

public class StuFactory{
    public Student getStudent(){
        return new Student();
    }
}


applicationContext.xml(核心配置文件)
<bean id="stu" class="com.bean.StuFactory"></bean>
<bean id="stuf" factory-bean="stu" factory-method="getStudent"></bean>

3)静态工厂的方式实例化

需要提供一个实例工厂方法创建 Bean 的实例。

实例类
public Student{
    public void testStudent(){
        System.out.println("静态工厂创建出来的对象")
    }
}
静态工厂类
public StaticFactory{
    public static Student getStudent(){
    return new Student();
    }
}

applicationContext.xml核心配置文件

<bean id="stu" class="com.bean.StaticFactroy" factory-method="getStudent"></bean>

测试代码
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu4 = ac.getBean("stu4", Student.class);
stu4.testStudent();
Student stu5 = ac.getBean("stu4",Student.class);
System.out.println("stu4===>" + stu4.hashCode());
System.out.println("stu5===>" + stu5.hashCode());

测试结果 👆

静态工厂创建出来的对象
stu4===>1558712965
stu5===>1558712965

4.Spring中Bean的作用域

Spring容器在初始化一个Bean的实例时,同时会指定该实例的有效范围

singleton单例模式,使用sinleton定义的Bean在Spring容器只有一个实例,这也是Bean默认的作用域。
prototype  原型模式,每次通过Spring容器获取prototype定义Bean时,Spring容器会创建一个新的Bean实例。
request在一次HTTP请求中,容器会返回该Bean的同一个实例。而对不同的HTTP请求会返回不同的Bean实例,该作用域仅限于当前的HTTP request内有效
session在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Session 内有效。
global Session在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。该作用域仅在使用 portlet context 时有效。

singleton : 单例模式

在 Spring 容器中只有一个实例,也是Bean 默认的作用域
<bean id="per" class="com.wangxing.demo4.PersonBean" scope="singleton"></bean>

ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
PersonBean personBean1=ac.getBean("per", PersonBean.class);
PersonBean personBean2=ac.getBean("per", PersonBean.class);
System.out.println("personBean1==="+personBean1.hashCode());
System.out.println("personBean2==="+personBean2.hashCode());
if(personBean1.equals(personBean2)){
   System.out.println("同一个对象");
}

运行结果:

personBean1===>1558712965
personBean2===>1558712965

prototype : 原型模式

每次通过 Spring 容器获取Bean 时,容器都将创建一个新的 Bean 实例。
<bean id="per" class="com.wangxing.demo4.PersonBean" scope="prototype"></bean>

ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
PersonBean personBean1=ac.getBean("per", PersonBean.class);
PersonBean personBean2=ac.getBean("per", PersonBean.class);
System.out.println("personBean1==="+personBean1.hashCode());
System.out.println("personBean2==="+personBean2.hashCode());
if(personBean1.equals(personBean2)){
   System.out.println("同一个对象");
}

运行结果

personBean1===>1558712965
personBean2===>208712506

5.Spring生命周期

Spring容器可以管理singleton作用域Bean的生命周期,再次作用域下,Spring也能够知道该Bean何时被创建,何时初始化完成,以及合适被销毁。

而对于prototype作用域的Bean,Spring只负责创建,当容器创建了一个Bean的实例后,Bean的实例就交给客户端代码管理,Spring容器将不再跟踪其生命周期。

了解Spring生命周期的意义在于,可以利用Bean在其存活的指定时刻做一些指定的操作。在一般情况下会在Bean被初始化或者销毁前执行一些操作。

在Spring中,Bean的生命周期是一个很复杂的执行过程,我们可以利用Spring提供一些定制的Bean创建过程。

Bean生命周期的整个执行过程描述。

1)根据配置情况调用Bean构造方法和工厂方法实例化Bean。

2)利用依赖注入完成Bean中所有属性值的配置注入。

3)如果Bean实现了BeanNameAware接口,则Spring调用了Bean的setBeanName()方法传入当前Bean的id。

4)如果Bean实现了BeanFactoryAware接口,则Spring调用setBeanFactroy()方法闯入当前工厂的实例引用。

5)如果Bean实现了ApplicationContextAware接口,则Spring调用setApplicationContext()方法,传入当前ApplicationContext实例引用。

6)如果BeanPostProcessor和Bean关联,则Spring将嗲偶哦那个该接口的于初始化方法

postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。

7)如果Bean实现了InitializingBean接口,则Spring将调用afterPropertiesSet()方法。

8)如果在配置文件中通过init-method属性指定了初始化方法,则调用该初始化的方法

9)如果BeanPostProcessor关联Bean关联,则Spring将调用该接口初始化方法。postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。

10)如果在<bean>中指定了该Bean的作用范围为scope="singleton",则将该Bean放入SpringIoC的缓存池中,将触发Spring对该Bean的生命周期管理;如果<bean>中指定了该Bean作用范围scope="prototype",则将该Bean交给调用者,调用者管理Bean的声明周期,Spring不在管理该Bean.

11)如果Bean实现了DisposableBean接口,则Spring会调用destory()方法将Spring中的Bean销毁;如果在配置文件中通过destory-method属性定义了Bean的销毁方法,则Spring调用该方法对Bean进行销毁。

代码例子:

测试类

public class InitMethods {
    public InitMethods(){
        System.out.println("Spring创建对象");
    }
    public void initConfiginfo(){
        System.out.println("Spring初始化方法");
    }

    private void destoryUse() {
        System.out.println("销毁一些对象,比如连接池等等");
    }
}

applicationContext.xml(Spring核心配置文件)

<bean id="initol" class="com.life.InitMethods" init-method="initConfiginfo" destroy-method="destoryUse"></bean>

测试主类

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
InitMethods initol = ac.getBean("initol", InitMethods.class);
AbstractApplicationContext ac1 = (AbstractApplicationContext) ac;
        // ac1.close();  //关闭容器
ac1.registerShutdownHook(); //销毁容器

无奈源不够强大

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值