Spring的使用以及基本原理

发送 三、Spring 的Ioc

 一、预备知识:反射

1.反射的基本概念

​    在运行期间,动态获取类的基本信息(类的属性、类的构造方法、类的普通方法)

 2.反射的使用Class

​    (1)获取Class对象的三种方式

package org.test;

import org.lanqiao.Student;

import java.lang.reflect.*;

public class Test {

    public static void getClassInfo(String className) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
        //第一种通过类.class获取Class对象
        //Class c = Student.class;
        //第二种方式:通过forName()
        //Class c = Class.forName(className);
        //第三种方式:通过类的对象获取类的信息
        Student student = new Student();
        Class c = student.getClass();

        //获取该类的属性
/*        Field[] fields = c.getFields(); //获取该类及从父类继承下来的所有公有public属性(不包括私有)
        for (Field field : fields) {
            System.out.println(field.getName());
            System.out.println(field.getType());
            System.out.println(Modifier.toString(field.getModifiers()));
        }*/
        //获取本类自己定义的所有的属性
       Field[] declaredFields = c.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
            System.out.println(declaredField.getType());
            System.out.println(Modifier.toString(declaredField.getModifiers()));
        }
        declaredFields[0].setAccessible(true);//暴力访问私有变量
        declaredFields[0].set(student,"赵六");

        System.out.println(student.getName());
        //Constructor[] constructors = c.getConstructors();
        /*for (Constructor constructor : constructors) {
            System.out.println(constructor.getName());
            System.out.println(constructor.getParameterCount());
            Parameter[] parameters = constructor.getParameters();
            for (Parameter parameter : parameters) {
                System.out.println(parameter.getName()+","+parameter.getType());
            }
        }*/
       /* Constructor constructor = c.getConstructor(int.class, String.class, int.class);
        Student student2 = (Student) constructor.newInstance(180,"张三",21);
        System.out.println(student2);
        *//*System.out.println(student.getName());*//*
        Method method = c.getMethod("study", String.class);
        method.invoke(student2,"王五");*/
       /* Method[] methods = c.getMethods();
        for (Method method : methods) {
            System.out.println(method.getReturnType());
            System.out.println(method.getName());
        }*/
     /*   Method[] declaredMethods = c.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println(method.getReturnType());
            System.out.println(method.getName());
        }
         declaredMethods[4].invoke(student,"李四");*/
        //System.out.println(o);
    }


    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException , NoSuchMethodException {
       getClassInfo("org.lanqiao.Student");
    }
}

 二、Spring框架的基本概念

1.Spring的基本概念

Spring是一个开源框架,它由[Rod Johnson](https://baike.baidu.com/item/Rod Johnson)创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

### 2.Spring的作用

IoC提供松耦合 ,解耦使用的

package org.test;

import org.lanqiao.IHello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        IHello hello = (IHello) applicationContext.getBean("hello");
        hello.sayHello();
    }
}
<?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">
    <!--委托Spring IoC容器创建并管理该bean的对象 -->
    <bean id="hello2" class="org.lanqiao.Hello"></bean>
    <bean id="hello" class="org.lanqiao.Hello2"></bean>
    <bean id="student" class="org.lanqiao.Student"></bean>
</beans>

  三、Spring 的Ioc

1.Ioc控制反转的概念

IoC  Inverse of Control  控制反转

把创建对象的方式在代码交给了Spring Container容器来创建

bean的创建、使用、销毁都交给IoC容器处理

2.Bean的生命周期

<bean id="hello2" class="org.lanqiao.Hello" init-method="init" destroy-method="d"></bean>

(1)创建

​    一种只要ioc容器启动,bean就被实例化,单例模式

​    一种是ioc容器启动时候并没有创建,而是在该对象被调用的时候才创建出来

(2)初始化 

init-method="init"

(3)使用

调用bean的普通方法

(4)销毁

destroy-method,并不是直接从内存中移除,而是做标记告知由GC来进行回收

### 3.Bean的范围

scope: 

singleton:单例(默认)

prototype:原型(多例)

在web的应用程序中:

scope=“request”

scope=“session”

scope=“application”

单例和多例的区别:

(1)单例是在IOC容器只存在一个对象,多例模式就会有多个对象

(2)单例模式只要ioc容器启动就会被创建,多例模式只有在使用的时候才被创建

​​​​​​​

四、Spring 的DI

DI dependency injection 依赖注入,给创建的bean的对象赋值

(一)根据依赖注入的方式

 1.属性注入方式

<bean id="student" class="org.lanqiao.Student">
        <!--依赖注入-->
        <property name="id" value="1"/>
        <property name="name" value="张三"/>
        <property name="age" value="21"/>
    </bean>

2.构造方法注入方式

可以通过构造方法的参数名,参数索引和参数类型等进行注入,推荐使用参数名(直观)

<!--Student student01 = new Student(2,"李四",21);-->
    <bean id="student01" class="org.lanqiao.Student">
        <constructor-arg name="id" value="2"/>
        <constructor-arg name="name" value="李四"/>
        <constructor-arg name="age" value="21"/>
        <!--<constructor-arg index="0" value="2"/>
        <constructor-arg index="1" value="李四2"/>
        <constructor-arg index="2" value="23"/>-->
    </bean>

 3.通过工厂方式注入

工厂的作用生产对象,可以在创建对象的同时做一些其他事情

 <!--使用非静态工厂-->
    <bean id="studentFactory" class="org.lanqiao.factory.StudentFactory"/>
    <bean id="student02" factory-bean="studentFactory" factory-method="create"/>
    <!--使用静态工厂-->
    <bean id="student03" class="org.lanqiao.factory.StudentFactory2" factory-method="create"/>

4.使用SpEL(spring expression language) #{},支持表达式

<bean id="student04" class="org.lanqiao.Student">
        <!--属性SpEL依赖注入,调用setXXX()-->
        <property name="id" value="#{1}"/>
        <property name="name" value="#{'张三'}"/>
        <property name="age" value="#{10+10}"/>
</bean>

5.使用P命名空间的方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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">
    <!--使用p命名空间 -->
    <bean id="student05" class="org.lanqiao.Student" p:id="5" p:name="孙七" p:age="22"/>
</beans>

根据属性值的类型

1.基本数据类型的注入

 <bean id="student" class="org.lanqiao.Student">
        <!--依赖注入-->
        <property name="id" value="1"/>
        <property name="name" value="张三"/>
        <property name="age" value="21"/>
    </bean>

 2.引用数据类型

<bean id="grade" class="org.lanqiao.Grade">
        <property name="id" value="1"/>
        <property name="gname" value="大一"/>
</bean>
<bean id="student06" class="org.lanqiao.Student">
        <property name="id" value="1"/>
        <property name="name" value="张三"/>
        <property name="age" value="21"/>
        <property name="grade" ref="grade"/>
</bean>

3.空值注入null

  <bean id="student07" class="org.lanqiao.Student">
        <property name="id" value="1"/>
        <property name="name" value="张三"/>
        <property name="age" value="21"/>
        <property name="grade">
            <!--注入空值-->
            <null></null>
        </property>
    </bean>

(三)Spring的自动装配

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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"
       default-autowire="byType">

    <bean id="grade" class="org.lanqiao.Grade">
        <property name="id" value="1"/>
        <property name="gname" value="大一"/>
    </bean>
    <bean id="student" class="org.lanqiao.Student">
        <property name="id" value="1"/>
        <property name="name" value="张三"/>
        <property name="age" value="21"/>
    </bean>

这里的 default-autowire="byType" 的设置表示:在student这个bean中有一个Grade属性没有被声明注入,自动在Spring IoC容器中查找与这个属性相匹配的类型,假如类型一致,会把容器中的这个值注入给该属性
byType不能在IoC中出现重复类型的bean,会造成混乱,不知道要注入哪个bean
byName就是通过属性名相同的bean会自动注入进来
这种设置是全局性,在整个IoC容器都会自动的根据类型或者名称装配,这种方式是有风险的,不建议这样使用
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值