Spring IOC AOP框架

I. Spring框架

Bean的实例化

1. Spring概述

1. Spring介绍 —— spring是什么

Spring是一个开源的轻量级应用开发框架,其目的是用于简化企业应用程序的开发,降低侵入性。

Spring提供的IOC和AOP功能,可以将组件的耦合度降至最低,即解耦,便于系统的维护和升级。

Spring为系统提供一个整体的解决方案,开发者可以利用它本身提供的功能外,也可以与第三方框架和技术整合应用,可以自由选择哪种技术进行开发。

Spring的本质是管理软件中的对象,即创建对象和维护对象之间的关系。

 

2. Spring容器

在Spring中,任何的Java类和JavaBean都被当成Bean对象处理,这些Bean是通过容器管理和使用
Spring容器有BeanFactory和ApplicationContext两种类型

Spring容器的实例化

ApplicationContext继承自BeanFactory接口,拥有更多的企业级方法(推荐)

加载工程classpath下的配置文件实例化

  String xml = "配置文件路径";

  ApplicationContext ac = new ClassPathXmlApplicationContext(xml);     

 Spring容器的使用

 从本质上讲,BeanFactory和ApplicationContext仅仅是一个维护Bean定义以及相互依赖关系的高级工厂接口,通过容器访问Bean定义。

 

首先在容器配置文件spring.xml中添加Bean定义

 <beanid="标识符" class="Bean类型(包名+类名)" /> 

<bean id="gregorianCalendar"  class="java.util.GregorianCalendar"></bean>

 

 然后在创建容器对象后,调用getBean()方法获取Bean的实例

 getBean("标识符")

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

Calendar c1 =  (Calendar) ac.getBean("gregorianCalendar");  //get到的是object类型,需要进行对象强转

System.out.println(c1);

 

 

 

2. Bean的实例化

Spring容器创建Bean对象的方式有以下三种:

   1) 用构造器的方式来实例化

   <!-- 通过构造器实例化Bean -->

   <!-- 会自动调用无参构造器创建对象 -->

   <bean id="gregorianCalendar"  class="java.util.GregorianCalendar"></bean>

 

   2) 静态工厂方法实例化

   <!-- 通过静态工厂方法实例化Bean -->

   <!-- factory-method属性用于指定工厂中创建Bean对象的方法 -->

   <bean id="calendar"  class="java.util.Calendar"  factory-method="getInstance"></bean>

 

   3) 实例工厂方法实例化

   <!-- 通过实例工厂方法实例化Bean -->

   <!-- factory-bean属性用于指定工厂Bean对象 -->

   <bean id="date"  factory-method="getTime"   factory-bean="gregorianCalendar"></bean>

 

Bean的命名

在Spring的容器中,每个Bean都需要有名字(即标识符),此名字可以用<bean>元素的id属性或者name属性指定

 

3. Bean的作用域

Spring容器在实例化Bean时,可以创建以下作用域的Bean对象

singleton:在Spring容器中一个Bean定义对应一个实例对象,默认项

prototype: 一个Bean定义对应多个实例对象

request:在一次Http请求中,一个Bean定义对应一个实例对象

session:在一次HttpSession中,一个Bean定义对应一个实例对象

Bean的作用域,可以通过<bean>定义的scope属性来指定

   <!-- Bean的作用域 -->

   <bean id="gregorianCalendarOne"  class="java.util.GregorianCalendar"  scope="singleton"></bean>

   <bean id="gregorianCalendarTwo"  class="java.util.GregorianCalendar"  scope="prototype"></bean>

 

 

4. Bean的生命周期

指定初始化回调方法

 <bean int-method=" "> 

指定销毁回调方法,仅适用于singleton模式的Bean

<bean destory-method=" "/>

在<beans>元素中的default-init-mehod属性,可以为容器中的<bean>指定初始化回调方法,也可以通过default-destroy-method属性为容器中的<bean>指定销毁回调方法

   <!--bean的生命周期-->

   <bean id="exampleBean" scope="singleton"  init-method="init"  class="com.xms.entity.ExampleBean"  destroy-method="destroy" ></bean>

 

AbstractApplicationContext aac = new ClassPathXmlApplicationContext("spring.xml");

ExampleBean exampleBean = ac.getBean("exampleBean",ExampleBean.class);

aac.close();  //close容器时才会调用destroy方法

 

 

 

5. Bean的延迟实例化

默认行为是在容器实例化的同时将单例模式的Bean提前进行实例化

延迟实例化的操作:在<bean>声明时指定其属性 lazy-init="true"

一个延迟实例化的Bean将在第一次被用到时实例化

注意:仅适用于单例模式

在<beans>元素中的default-lazy-init属性,可以为容器中的<bean>指定延迟实例化特性

<bean id="exampleBean" scope="singleton"  init-method="init"  class="com.xms.entity.ExampleBean"  destroy-method="destroy"  lazy-init="true"></bean>

 

 

 

 

6.  基于注解的组件扫描

   什么是组件扫描?

   指定一个包路径,Spring会自动扫描此包及其子包中所有的组件类,当发现组件类定义前有特定的注解标记时,就将此组件纳入到Spring容器, 等价于原有的XML配置中的<bean>定义

   组件扫描可以替代大量XML配置的<bean>定义 

   指定扫描路径,使用组件扫描,首先需要在XML配置中指定扫描父级package路径

  <context:component-scan  base-package="com.xms"/>

<!-- 开启注解扫描 -->

    <context:component-scan base-package="com.xms"></context:component-scan>

 

  容器会自动扫描指定包及其子包下所有的组件类,如果此组件类定义前有特定的注解标记,则会实例化为Bean对象。

  

   自动扫描的注解标记

  @Component 通用注解

  @Repository  持久层组件注解

  @Service      业务层组件注解

  @Controller   控制层组件注解

   自动扫描组件的命名

   当一个组件在扫描过程中被检测到时,会生成一个默认的id值,默认id为小写开头的类名,也可以在注解标记中自定义id

  

   指定组件的作用域

   通常受Spring容器管理的组件,默认作用域是“singleton”,如果需要其他的作用域可以使用@Scope注解,只要在注解中提供作用域的名称即可

     

   指定初始化和销毁回调方法

  @PostConstruct 和 @PreDestroy注解标记分别用于指定初始化和销毁回调方法

    

   注解类型中默认取消了延迟加载

@Component("example") //此处注解可以指定id

@Scope("singleton") 

public class ExampleBean {

   

    public ExampleBean(){

         System.out.println("实例化ExampleBean:"+this);

    }

   

    @PostConstruct //初始化方法

    public void init(){

         System.out.println("初始化ExampleBean");

    }

   

    @PreDestroy  //销毁方法

    public void destroy(){

         System.out.println("销毁ExampleBean");

    }

}

 

 

 

Bean参数值的注入

1. Spring IOC

IOC全称,被翻译为控制翻转

IOC是指程序中对象的获取方式发生反转,由最初的new的方式创建,转变为由第三方框架创建,注入(DI),可以降低对象之间的耦合度

 

Spring容器采用DI方式实现IoC控制,IOC是Spring框架的基础和核心

DI全称是DependencyInjection,被翻译成依赖注入

DI的基本原理是将一起工作具有关系的对象,通过方法参数传入建立关系,因此容器的工作就是创建Bean时注入依赖关系

IOC是一种思想,而DI是实现IOC的主要技术途径

DI主要有两种注入方式,即Setter注入和构造器注入

 

1) Setter注入

   通过调用无参构造器或无参static工厂方法实例化Bean之后

   调用此Bean的Setter方法,即可实现setter方式的注入

<!-- Setter注入 -->

    <bean id="computer"  class="com.xms.entity.Computer"  >

         <property name="cpu"  value="Inter"></property>

         <property name="mainboard" >

             <value>华硕</value>

         </property>

         <property name="memory"  value="金士顿"></property>

         <property name="caliche"  value="希捷"></property>

    </bean>

 

 

2) 构造器注入

   通过调用带参数的构造器来实现,容器在Bean被实例化时候,根据参数类型执行相应的构造器

<!-- 构造器注入-->

    <bean  id="mobilePhone"  class="com.xms.entity.MobilePhone">

         <!-- 默认是String类型的构造器,如果要其他的参数,需要设定type,如 type="java.lang.Integer" -->

         <constructor-arg index="0"  value="Inter"  type="java.lang.String"></constructor-arg>

         <constructor-arg index="1"  value="4G" type="java.lang.String"></constructor-arg>

    </bean>

 

 

自动装配

Spring容器可以自动装配(autowire)相互协作Bean之间的关联关系,autowire可以针对单个Bean进行设置,方便之处在于减少xml的注入配置

在配置文件中,可以在<bean>元素中使用autowire属性来指定自动装配的规则,

一共有四种类型值,

no:禁用自动装配,默认值

byName:根据属性名自动装配,此选项将检查容器,根据名字查找与属性名一致的Bean,然后将其与属性自动装配(setter注入)

byType:如果容器中存在一个与指定属性类型相同的Bean,则将与此属性自动装配(setter注入)

constructor:与byType方式类似,不同之处在于它应用于构造器参数的方式

<!-- 自动装配 -->

    <bean id="student"  autowire="constructor"  class="com.xms.entity.Student"></bean>

 

 

 

 

 

2.  参数值注入

1) 注入基本值

       <value> 元素可以通过字符串指定属性或构造器参数的值

       容器将字符串java.lang.String类型转换为实际的属性或参数类型

       然后给Bean对象注入 

<!-- Setter注入 -->

    <bean id="messageBeanOne"  class="com.xms.entity.MessageBean"  >

         <!-- 基本值 -->

         <!-- setter注入 -->

         <property name="name">

             <value>张三</value>

         </property>

         <property name="age"  value="18"></property>

    </bean>

 

 

   2) 注入bean对象

       注入外部Bean(引用方式,方便重用)

<!-- Setter注入 -->

    <bean id="messageBeanOne"  class="com.xms.entity.MessageBean"  >

         <!-- Bean对象 -->

         <property name="user"  ref="user"></property>

    </bean>

    <bean id="user"  class="com.xms.entity.User">

         <property name="name"  value="李四"></property>

         <property name="age"  value="18"></property>

    </bean>

 

   3) 注入集合

      通过<list>,<set>,<map>,<props>元素可以定义和设置与Java类型中对应的List,set,Map及Properties的属性 

     List,Set,Map及Properties都可以采用引入方式注入<util:list>,<util:set>

<util:map>,<util:properties>

<!-- Setter注入 -->

    <bean id="messageBeanOne"  class="com.xms.entity.MessageBean"  >

         <!-- List -->

         <property name="languages">

             <list>

                 <value>C++</value>

                 <value>Java</value>

                 <value>PHP</value>

                 <value>Python</value>

             </list>

         </property>

        

         <!-- Set -->

         <property name="cities">

             <set>

                 <value>北京</value>

                 <value>西藏</value>

                 <value>云南</value>

                 <value>青岛</value>

             </set>

         </property>

        

         <!-- Map -->

         <property name="scores">

             <map>

                 <entry key="JSD1706"  value="95"></entry>

                 <entry key="JSD1704"  value="100"></entry>

             </map>

         </property>

        

         <!-- Properties -->

         <property name="ps">

             <props>

                 <prop key="user">root</prop>

                 <prop key="password">1234</prop>

             </props>

         </property>

    </bean>

 

<!-- 采用引用方式注入集合 -->

    <!-- 声明集合 -->

    <util:list id="list">

         <value>C++</value>

         <value>Java</value>

         <value>PHP</value>

         <value>Python</value>

    </util:list>

   

    <util:set id="set">

         <value>北京</value>

         <value>西藏</value>

         <value>云南</value>

         <value>青岛</value>

    </util:set>

   

    <util:map id="map">

         <entry key="JSD1706"  value="95"></entry>

         <entry key="JSD1704"  value="100"></entry>

    </util:map>

   

    <util:properties id="ps">

          <prop key="user">root</prop>

          <prop key="password">1234</prop>

    </util:properties>

   

    <bean id="messageBeanTwo"  class="com.xms.entity.MessageBean">

         <!-- 基本值 -->

         <!-- setter注入 -->

         <property name="name">

             <value>张三</value>

         </property>

        

         <property name="age"  value="18"></property>

        

         <!-- Bean对象 -->

         <property name="user"  ref="user"></property>

   

         <!-- 集合 -->

         <property name="languages" ref="list"></property>

         <property name="cities"  ref="set"></property>

         <property name="scores"  ref="map"></property>

         <property name="ps"  ref="ps"></property>

    </bean>

 

   4) 注入spring表达式

      Spring表达式,和El表达式在语法上很相似,可以读取一个

 

<!-- 加载属性配置文件 -->

    <util:properties id="ds"   location="classpath:db.properties"></util:properties>

 

   <bean id="demoBean"  class="com.xms.entity.DemoBean">

         <property name="name"  value="#{user.name}"></property>

         <property name="language"  value="#{list[0]}"></property>

         <property name="city"  value="#{messageBeanOne.cities[0]}"></property>

         <property name="score"  value="#{map.JSD1704}"></property>

         <property name="pageSize"  value="#{ds.pageSize}"></property>

    </bean>

 

   5) 注入null或字符串

  Spring将属性的空参数当做空String

  <bean>

       <property name="name" value=""/>

  </bean>

   如果需要注入NULL值,可以使用<null>元素

  <bean>

      <property name="name">

         <null/>
       </property>

  </bean>

3.  基于注解依赖注入

3. 基于注解依赖注入

   具有依赖关系的Bean对象,可以使用以下任意一种注解实现

  @Autowired /@Qualifer

       可以处理构造器注入和setter注入

      Autowired写在构造器或set方法前,声明需要为其注入Bean,@Qualifer写在参数前面,声明需要注入的Bean的id值

@Component

public class Programmer {

   

    private Computer computer;

   

    public Programmer(){}

   

    @Autowired

    public Programmer(@Qualifier("computer")Computer computer){

         this.computer = computer;

    }

   

    public Computer getComputer(){

         return computer;

    }

}

 

  @Autowired也可以写在属性上,作用和写在set方法上类似,但是只会执行一行代码(赋值)

@Component

public class Student {

   

    @Autowired

    @Qualifier("computer")

    private Computer computer;

 

    public Computer getComputer() {

         return computer;

    }

 

    public void setComputer(Computer computer) {

         System.out.println("我是Computer");

         this.computer = computer;

    }

}

 

   注意:注入对象是单例时,@Qualifer可省略,此时Spring按照类型匹配参数

 

  @Resource

       只能处理Setter注入

       注意:注入对象是单例时,(name=“标识符”)可省略,此时Spring按照类型匹配参数

@Component

public class Manager {

   

   

    private Computer computer;

 

    @Resource

    public void setComputer(Computer computer) {

         System.out.println("我是Manager");

         this.computer = computer;

    }

 

    public Computer getComputer() {

         return computer;

    }

}

 

  @Resource也可以写在属性上,作用和写在set方法上类似,但是只会执行一行代码(赋值代码)

  @Inject/@Named

   和@Autowired/@Qualifer用法一致,需要额外导包

  @Inject注解标记时Spring3.0 开始增添的对JSR-330标准的支持,需要添加JSR-330的jar包,javax.inject-1.jar

 

  @Inject/@Named注解用法和@Autowired/@Qualifer一致,其中@Inject等价于@Autowired,@Named等价于@Qualifer

      

   注入基本值或Spring表达式值

  @Value注解可以注入基本值或Spring表达式值

    @Value("Inter")

    private String cpu;

 

    @Value("华硕")

    private String mainboard;//主板

    private String memory;//内存

    private String caliche;//硬盘

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值