Spring IOC

欢迎访问:我的个人网站

Spring框架提供了非常多的模块,如果使用基本的Spring功能,需只需要引入其核心的几个包即可,前四个正是Spring位于核心容器内的几个模块。后两个与日志相关。

  • spring-beans
  • spring-core
  • spring-context
  • spring-expression
  • commons-logging
  • log4j

1.IOC

IOC可以接管对象的实例化工作,不用自己去创建,只需进行相关的配置即可完成,IOC实际上是通过读取我们配置的xml文件,使用dom4j进行解析,获取我们所需要实例化的类所在的包,以及实例化该类时所需要提供的id。然后通过反射加载这个被接管的类,后续我们可以获取,一个简单案例演示一个类被接管并获取到的过程:

(1)新建工程,导包
(2)新建一个对象Person,后续让Spring接管这个类的实例化工作:

public class Person {
   private String name;
   private Integer age;
   //省略get/set
}

(3)新建Spring配置文件并注入Person,配置文件中的头可以从下载Spring时附带的文件夹schema中寻找。如果使用了IDEA,新建spring配置文件时将自动引入头:

<?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">
      
   <!--使用无参数构造方法进行构建, 如果此时没有默认无参数构造方法,会报错-->
   <bean id="person" class="com.bestbigkk.domain.Person">
   </bean>
</beans>

(4)通过Spring获得一个Person对象:

public class Main {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
        Person person = (Person) context.getBean("person");
        System.out.println(person);
    }
}

2.bean 实例化三种方式

(1)配置文件,指定一个bean注入, 这种方式使用无参数构造方法进行构建, 如果此时没有默认无参数构造方法,会报错no default construct found…

   <bean id="person" class="com.bestbigkk.domain.Person">

(2)使用静态工厂,创建静态方法返回类对象。需要在配置bean的时候,为其指定一个beanFactory工厂,并指定这个工厂里面哪个静态方法是用于获取bean的实例的,后续再获取这个bean实例时候,相当于直接使用了:工厂类名.获取实例静态方法名 的形式获取bean的一个实例:

public class Person {
    private String name;
    private Integer age;
    //...
}

public class PersonFactory {
    public static Person getBean(){
        System.out.println("静态工厂获取实例");
        return new Person();
    }
}

配置这个bean,之后就可以获取其实例:

 <bean id="person" class="com.bestbigkk.domain.PersonFactory" factory-method="getBean"></bean>

(3)使用实例工厂,通过一个工厂的实例对象来获取bean的对象。需要如下流程:

创建一个bean的实例化工厂:

public class PersonFactory {
    public Person getBean(){
        System.out.println("实例工厂获取实例");
        return new Person();
    }
}

配置beanFactory实例化工厂:

<bean id="personFactory" class="com.bestbigkk.domain.beanFactory"> </bean>

配置person,指定实例化它的工厂以及实例化方法:

<bean id="person" factory-bean="personFactory" factory-method="getBean"> </bean>

3.bean标签常用含义:

  • id: 指定这个bean在注入的时的名字,后续我们通过工厂getBean(name)获取某个对象的时候,提供其注入时候的名字即可。不能包含特别符号。
  • class: 被注入bean的全路径。
  • name: 与id类似,但是id中不能包含特殊符号,这里可以。name实际上是遗留的,还是使用id属性即可。
  • scope: 指定被注入bean的作用范围,存在以下几个选项:
    • singleton:默认值 ,单例的,这个对象只会创建一次,可以连续获取两个对象比较其内存地址。
    • prototype:多例的,每次创建都是一个新的对象。
    • request:WEB项目中,Spring创建一个Bean对象,将其存在于request对象中。
    • response:WEB项目中,Spring创建一个Bean对象,将其存在于response对象中。
    • session:WEB项目中,Spring创建一个Bean对象,将其存在于Session对象中。
    • globalSerssion:WEB项目中,应用在prolet环境中,如果没有prolet环境,那么和Session一样,放在Session域里面。

4.bean标签的属性注入:

在实例化一个对象的时候,可以选择为这个对象设置一些值, 在Java中可以选择使用以下常规的方式进行注入:

DDDDDDDDDDDDDDDDDD  Java中属性注入的三种形式  DDDDDDDDDDDDDDDDDDD

在Spring中仅仅支持set方法注入(使用较多) 以及构造方法注入,示例:

创建一个Bean:

public class Person {
   private String name;
   private Integer age;

   public Person(){

   }
   public Person(String name, Integer age){
       this.age = age;
       this.name = name;
   }
   
   public String getName() {
       return name;
   }

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

   public Integer getAge() {
       return age;
   }

   public void setAge(Integer age) {
       this.age = age;
   }
}

使用有参构造注入:

需要在配置bean的时候,指定要注入的属性以及值, 指定的参数个数必须有构造函数可以匹配上,否则无法实例化。在正确配置之后,实例化这个bean的时候就会使用指定的构造方法初始化并赋值::

 <bean id="person" class="com.bestbigkk.domain.Person" scope="prototype">
           <constructor-arg name="age" value="21"> </constructor-arg>
           <constructor-arg name="name" value="KK"> </constructor-arg>
 </bean>

获取实例:

Person person1 = (Person) context.getBean("person");  
System.out.println(person1.toString());

//结果:
Person{name='KK', age=21}

使用set方法注入属性:

实例化一个bean的时候,使用set方法进行设置:需要在配置bean之后,使用property标签指定设置的属性名以及属性值即可完成注入,需要注入的属性必须为其提供set方法。对于简单属性类型可以使用下面的方式直接注入:

<bean id="person" class="com.bestbigkk.domain.Person" scope="prototype">
     <property name="name" value="KK"> </property>
</bean>

在某些情况下,一个对象里面会包含另外一个对象,比如在Web开发中,Service层需要使用使用Dao层中的对象来完成数据库的持久化操作,此时可以考虑将Dao层中的对象直接注入到Service中的对象,不再使用new的方式进行, 针对这一情况也可以使用set方法进行注入:

使用一个简单的例子来表示这种注入方式:一个Person类表示一个学生,其中包含了一个表示成绩的对象Score,由于Person引入了Score对象,可以使用set形式进行注入

(1)创建Score:

public class Score {
   private Integer math;
   private Integer chinese;
}

(2)创建Person:

public class Person {
  private String name;
  private Integer age;
  private Score score;

  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
  public Integer getAge() { return age; }
  public void setAge(Integer age) { this.age = age; }
  public Score getScore() { return score; }
  public void setScore(Score score) { this.score = score; }
}

(3)配置Score:

<bean id="score" class="com.bestbigkk.domain.Score"> </bean>

(4)配置Person, 并注入Score对象,使用ref属性指定引用哪个bean的id作为对象注入。本例子中注入Score对象,且配置的Score类id为score:

<bean id="person" class="com.bestbigkk.domain.Person"> 
    <property name="score" ref="score">
</bean>

P命名空间注入

(1)需要修改.xml文件的文件头:

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

新增:
    xmlns:p="http://www.springframework.org/schema/p"

(2)在配置的bean里面配置属性,此时p将作为一个属性存在,使用[p:属性名]的形式为指定的属性设置值:

<bean id="person" class="com.bestbigkk.domain.Person" p:name="KK" p:age="21"></bean>

注入复杂数据类型

Spring允许向一个对象里面注入复杂的数据类型,比如数组,List,Map, Properties数据:

//节约篇幅,省略了getXXX()/setXXX()方法,如果运行中无setXXX()方法会报错。
public class Person {
    private String[] hobby;
    private List<Integer> score;
    private Map<Integer, String> map;
    private Properties properties;
}

为这个bean注入属性:

 <bean id="person" class="com.bestbigkk.domain.Person" scope="prototype">
 
            <!--注入数组, List类型的数据-->
            <property name="hobby">
                <list>
                    <value>音乐</value>
                    <value>旅行</value>
                </list>
            </property>
            <property name="score">
                <list>
                    <value>100</value>
                    <value>200</value>
                </list>
            </property>
            
            <!--注入map类型的数据-->
            <property name="map">
                <map>
                    <entry key="1" value="A"> </entry>
                    <entry key="2" value="B"> </entry>
                    <entry key="3" value="C"> </entry>
                    <entry key="4" value="D"> </entry>
                    <entry key="5" value="E"> </entry>
                </map>
            </property>
            
            <!--注入Properties类型数据-->
            <property name="properties">
                <props>
                    <prop key="userName">KK</prop>
                    <prop key="userPwd">123</prop>
                </props>
            </property>
        </bean>

5.使用注解进行Bean的管理

5.1注解

注解是一种存在于代码里面的特殊标记,使用不同的注解可以完成它所约定的功能。注解可以使用在类上面,属性上面,方法上面。

Spring里面使用注解的话,除了使用一些核心包之外,还需要使用spring-aop包,关于注解的一些操作被包含在这个包里面。

在使用注解进行开发的时候,在.xml配置文件中,约束也需要进行适当得人更新,需要进行调整(引入了spring-context.xsd)。需要在文件中开启注解扫描。然后就可以在代码使用注解。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
       
       <!--开启注解方式1,扫描类,方法,属性-->
       <context:component-scan base-package="com.bestbigkk.domain"></context:component-scan>

       <!--开启注解方式2,仅仅扫描属性上面的注解-->
       <context:annotation-config></context-annotation-config>

</beans>

开启注解指的是Spring将通过配置的包进行注解的扫描,进而按照1注解实现不同功能,base-package指定了要扫描的范围:

  • 可以为多个包, 使用逗号分隔:base-package=“com.bestbigkk.domain, com.bestbigkk.service”
  • 会扫描指定包下的所有嵌套包,base-package=“com”, 则扫描com下的所有类以及子包中的类。

5.2使用注解创建对象

在目标类对象上面使用 @Component 即可:

@Component
public Class Person{
    //... 
}
等价于:
<bean id="person" class="com.bestbigkk.domain.Person"></bean>

@Component 注解允许设置一个属性value,作为实例化id的值,如果未设置(如上),则id值默认为当前类的全小写名称,也就是:person。当然也可以自己设置,后续获取实例的时候需要使用该值:

@Component(value="PERSON")
public class Person{
    //...
}

classPathXmlApplicationApplication.getBean("PERSON");

创建对象有4个注解,除了 @Component 之外,还衍生出来三个另外的注解,他们的功能来讲都是一致的,但是为了更方便开发过程中区分层与层之间的关系。使得其用途更加清晰。

  • @Controller: 控制层
  • @Service: 服务层
  • **@Repository:**持久层

在创建对象的时候,如要指定这个对象的作用域,可以使用**@Scope**注解进行标注,这个注解默认值也是singleton,如果要改变的话,只需要为其属性value赋值即可:

@Controller(value="Person")
@Scope(value="prototype")
public class Person(){
    //...
}

5.3使用注解注入属性

使用注解方式注入属性的时候,不需要为属性设置对用的set方法,注入属性使用**@Autowired** 进行设置,当对一个属性添加了**@Autowired** 注解的时候,Spring会检查这个属性所属的类,并再工程中进行扫描以查询这个类, 最后注入。针对这个示例,Spring会去寻找一个名为Score的类,而不是通过Score类上的**@Component** 注解的值确定的。

//被注入类
@Component
@Scope(value = "prototype")
public class Score {
    public Integer math = 1;
    public Integer chinese = 2;
}

//注入类
@Component
@Scope(value = "prototype")
public class Student {
    private String name;
    private Integer age;

    @Autowired
    private Score score;
}

除了使用**@Autowire** 注解之外,属性的注入还可以使用**@Resource** 进行处理, @Autowire 是自动寻找被加载的类进而注入,而**@Resource** 注解则是确定要为其制定一个属性name 来确认注入哪个类,name的值需要与被注入对象的 @Component(value) 注解值一致。

根据上面所述,可以将注解+配置文件的混合使用,在.xml文件里面配置bean,然后用**@Resource(name=“Bean的ID值”)** 注入对象。

@Component
@Scope(value = "prototype")
public class Student {
    private String name;
    private Integer age;

    @Resource(name="score") 
    private Score score;
}

6.IOC 与 DI的区别

IOC : 控制翻转,通过对bean进行配置,让Spring接管对Bena的实例化工作。
DI : 依赖注入,指的是在创建对象的时候,可以为这个对象的2属性注入值。
DI 需要依赖于IOC进行,因为IOC进行对象的实例化工作,如果没有进行实例化,那么就谈不上为这个对象的属性设置值。

7Spring整合Web项目原理

在以上的所有示例中,从Spring获取我们配置好的对象都是通过ClassPathXmlApplicationContext类进行的,这样虽然可以使用,但是在真正的WEB开发中,如果使用了上面的这种方法,那么所有请求来到一个Service时候,都要建立一个ClassPathXmlApplicationContext对象进行操作,这样的话对资源使用使很不友好的。Spring针对这个问题做了以下的处理流程: 在服务器启动的时候,也就是ServletContext初始化的时候,通过监听器直到何时初始化完毕,然后建立这个对象加载Spring的配置文件,并将这个对象加入到ServletContext域里面去。以完成进行初始化工作。后续在获取对象的时候,首先到ServletContext获取ClassPathXmlApplicationContext对象,然后得到对象。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值