Spring框架(二)

紧接上一节,继续说Spring Bean对象

Spring Bean对象

1.1 Bean对象的命名

当我们把对象交给Bean容器管理时都要给他配一个名字,使用id或name属性,如下在Bean标签中

<bean id="date1" class="java.util.Date"/>

当然我们不指定的话,系统会默认制定一个,规则是首字母小写的类名,如date

1.2 Bean对象的实例化

Spring容器创建Bean对象的方法有如下3种方式:

1.  通过构造器实例化Bean对象.
    <bean id="date1"  class="java.util.Date"/>
2.  通过静态工厂方法实例化Bean对象.
    <bean id="c1" class="java.util.Calendar" factory-method="getInstance" />
        这里代表通过Calendar对象的getInstance静态方法获得此对象
3.  通过实例工厂方法实例化Bean对象.
    <bean id="date" factory-bean="c1" factory-method="getTime"/>
        此处我们通过factory-bean标签制定一个实例化的对象的方法来创建Date对象

1.3 Bean对象的作用域

我们就不按照书本上解释了,所谓Bean对象的作用域指的就是它在内存中有几份,一般默认的作用域是单例模式,也就是创建出来一份取用都只是这一个,另一种常用的是多例模式,也就是每次获取都是一个新建的实例.还有需要注意的是单例模式下对象的创建销毁都由Spring来管理,而多例模式下spring只管创建,不管销毁.

1)singleton(单例):每次从容器获取返回的都是一个对象(内存中此类的实例只有一份),Spring中bean的默认作用域

2)prototype(多例):每次从容器获取都创建一个新的类的实例销毁不由Spring管理


<bean id="helloService"  class="memory.HelloService"   
      scope="prototype"   
      init-method="init" 
      destroy-method="destroy"/>
<!-- 我们可以在此指定init和destroy也就是创建和销毁的方法,也可以不指定 -->

注:面试的时候可能会被问到,单例模式有什么坏处吗?

答:单例设计在对内部实例变量进行非原子操作有可能有线程安全问题.

以后我们有可能讲到单例模式如何设计?留个期待吧

1.4 Bean对象的延迟加载

延迟加载指的就是先不要让Spring创建出配置的对象,当需要时再创建.一般我们将一些大的不常用的对象设定延迟加载,这样做的好处是系统启动快,内存开销小.

单独为一个对象延迟加载就在bean标签中加上 lazy-init=“true” 属性

我们也可以进行全局的延迟加载,那么就在beans标签中加上 default-lazy-init="true"

而当我们有些对象需要立即加载,可以将延迟加载设为false

举个例子


<?xml version="1.0" encoding="UTF-8"?>
<beans 
    default-lazy-init="true"
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:p="http://www.springframework.org/schema/p"
    .....
    
      <bean 
            id="date"
            class="java.util.Date"
            lazy-init="false"/>    
</beans>

下面填一下上节留下的坑---DI(Dependency Injection)依赖注入

Spring Bean 依赖

2.1 依赖注入DI

简单直白:就是给参数注入值

我们在创建对象时通常会使用构造方法或者set方法给属性注入值,使用Spring管理对象同样的也有对应的两种方式

Spring 容器中的Bean对象通常会存在一定的依赖关系,而这种依赖关系的实现在Spring 框架中要借助于DI机制。其中DI就是借助对象管理对象依赖关系的一个过程。

Spring中提供的依赖注入方式有构造注入和set注入,其中构造注入就是借助构造方法的参数实现对类中属性值的注入,set注入就是借助set方法的参数实现其属性值的注入。

Spring 依赖注入时,可以实现基本值的注入,Bean对象的注入,集合的注入,spring表达式方式的注入等等。

set注入的配置(重点)


<!-- 在bean标签中对需要注入的属性加入property标签 -->
<bean id="dataSource1" class="com.company.spring.util.DataSource">
         <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
         <property name="url" value="jdbc:mysql:///test"/>
         <property name="username" value="root"/>
         <property name="password" value="root"/>
</bean>

构造注入(了解)


<!--加入constructor-arg标签,spring会根据参数顺序注入-->
<bean id="dataSource2" class="com.company.spring.util.DataSource">
         <constructor-arg value="com.mysql.jdbc.Driver"/>
         <constructor-arg value="jdbc:mysql:///test"/>
         <constructor-arg value="root"/>
         <constructor-arg value="root"/>
</bean>

2.2高级注入

除了注入一些单个值或对象的注入,还有复杂类型注入的方式,如数组,集合.再次挖坑(别打我),放到下一节讲

2.3 自动装配

简单直白:让Spring直接从bean容器中找到属性对应的的合适的bean对象自动注入进去

Spring IOC容器可以自动装配(autowire)相互协作bean之间的关联关系,不用自己写set注入构造注入

autowire可以针对单个bean进行设置,autowire的方便之处在于减少xml的注入配置

Spring 配置文件中通过bean元素的autowire属性指定自动装配规则,一共有四种类型值

属性值 描述
1. no 禁用自动配置(默认)
2. byName 按名字自动装配(重点掌握),有名字相同类型不同的风险
3. byType 按类型自动状态(重点掌握),但有多个类型时会出错
4. constructor 与byType类似,不同之处在于它应用于构造器参数。

例如:


 <bean id="jdbcTemplate3" 
             class="com.company.spring.injection.JdbcTemplate"
             autowire="byType">
  </bean>
<!--注:byType时有类型相同的对象会报错找到重复类型的对象
    No qualifying bean of type 'beans.DataSource' available: expected single matching bean but found 2: dataSource,dataSource1-->

实际当中自动装配并不常用,了解,了解(估计又有人要打我)

今日扩展内容

==================================================

我们就来模拟一下如何通过反射动态调用方法模拟spring如何找到的set方法


Scanner sc=new Scanner(System.in);
System.out.println("please input class");
//java.util.Date
String pkgCls=sc.nextLine();
System.out.println("please input method");
//getTime
String methodName=sc.nextLine();
//1.构建类对象
Class<?> c=Class.forName(pkgCls);
//2.获取类中方法对象
Method m=c.getDeclaredMethod(methodName);
//3.执行类的对象的方法
Object obj=c.newInstance();
Object result=m.invoke(obj);
System.out.println(result);
sc.close();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值