Spring-SecondDay

自动装配

我们进行对象注入的时候有两种方式

  • 1 set方法注入
<property name="uerDao" ref="userDao" />
  • 2 构造方法注入
<constructor-arg>

    <ref bean="userDao"/>

</constructor-arg>

现在来学习自动注入,就是不需要指定以上两种方式

Autowire : 自动装配,两种取值

  1. 1 byName
  2. 2 byType  

byName

byName是根据setter方法名字进行匹配,如果找不到,就不赋值

如 setUserDao 方法  就会找userDao,如果 bean的ID为 UserDao 也一样找不到,区分大小写

设置方式

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">

</bean>

<bean id="userService" class="com.tledu.zrz.service.UserService"  

 autowire="byName">

</bean>

byType

byType是根据setter方法的参数列表中的数据类型进行匹配,如果beans.xml中出现了多个相同类型的对象,就会报错

如 setUserDao(UserDao userDao) 方法  就会找UserDao,如果是接口,就找对应的实现类对象

设置方式

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">

</bean>

<bean id="userService" class="com.tledu.zrz.service.UserService"  

 autowire="byType">

</bean>

注意 : 使用自动装配,需要有公共的无参构造,虽然这里就算是私有化构造方法也依然可以创建对象,但是还是提供一个公共的比较好,万一别的框架需要呢

生命周期和迟加载

生命周期

之前servlet的生命周期

构造方法 -- init -- service -- destroy  

那么spring创建对象的生命周期呢?

Spring中是没有init、service和destroy的,但是我们可以指定某个方法在创建完对象之后执行,某个方法在最后销毁的时候执行.

public void init(){
  System.out.println("init--------");
    }
    public void destroy(){
  System.out.println("destroy----------");
    }
    public UserService() {
  System.out.println("service构造方法");
}

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
    </bean>
    <!--  
  init-method : 用于设置初始化的方法
  destory-method : 用于设置销毁资源的方法
  -->
    <bean id="userService" class="com.tledu.zrz.service.UserService"  
  autowire="byName"   init-method="init" destroy-method="destroy"  >
    </bean>

Destroy之所以会执行,是因为我们默认创建对象的时候是单例模式

这个时候对象的生命周期会和Spring容器的生命周期绑定到一起,所以当我们销毁Spring容器的时候,会把所有的对象销毁,并自动调用destroy方法

但是如果我们把scope设置为prototype的时候,对象的生命周期就不会再和Spring容器绑定,销毁Spring容器的时候也就不会再执行该对象的destroy方法

比如

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
    </bean>
    <!--  
  init-method : 用于设置初始化的方法
  destory-method : 用于设置销毁资源的方法
  -->
    <bean id="userService" class="com.tledu.zrz.service.UserService"  scope="prototype"
  autowire="byName"   init-method="init" destroy-method="destroy"  >
</bean>

注意:scope为prototype类型时,我们容器只负责实例的创建,创建之后的生命周期由调用者负责。

迟加载

Spring容器默认是在执行

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

进行解析的时候创建对象并调用init,

如果我们不想让某个类在解析的时候就创建对象,而是用到的时候在创建对象的话,就需要设置迟加载

比如想要对userService迟加载可以这样设置

1.相关类

public UserDaoImpl(){
  System.out.println("Dao构造方法");
}
public UserService() {
  System.out.println("service构造方法");
}

2.配置

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
<bean id="userService" class="com.tledu.zrz.service.UserService"  scope="prototype"
      autowire="byName"   init-method="init" destroy-method="destroy" lazy-init="true"  >
</bean>

3.测试

@Test
    public void testAdd() {
  ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
    "beans.xml");
}

这时,不使用getBean方法就会报错,因为迟加载

通过结果可以看出,UserService的对象没有创建,那么什么时候创建呢?

UserService userService = (UserService) applicationContext.getBean("userService");

当调用getBean()的时候创建

或者是使用到这个对象的时候,比如我们获取userService对象,但是需要将userDao对象注入到userService中,那么这时候就算没有通过getBean(“userDao”) 而是通过getBean(“userService”)  也会创建userDao对象,因为在UserService中用到userDao了

为了使用方便,Spring还提出了default-lazy-init="true"

比如我们通过xml创建了10个对象,这10个对象都需要迟加载,那么每个bean标签中都设置lazr-init是比较麻烦的

于是我们可以在beans标签中添加default-lazy-init="true" 对所有的bean进行迟加载  

default-lazy-init 和 lazy-init 可以同时存在,比如 10个对象中 只有一个不需要迟加载,那么可以使用 default-lazy-init = true 全部设置迟加载,然后再去指定的bean中添加 lazy-init=false 就可以

<?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"  default-lazy-init="true" >

IOC注解

XML和注解的区别

XML配置

优点有:  

  1. XML配置方式进一步降低了耦合,使得应用更加容易扩展,即使对配置文件进一步修改也不需要工程进行修改和重新编译。

  2. 在处理大的业务量的时候,用XML配置应该更加好一些。因为XML更加清晰的表明了各个对象之间的关系,各个业务类之间的调用。同时spring的相关配置也能一目了然。  

缺点有:

        配置文件读取和解析需要花费一定的时间,配置文件过多的时候难以管理,无法对配置的正确性进行校验,增加了测试难度。

annotation配置

优点有:  

  1. 在class文件中,可以降低维护成本,annotation的配置机制很明显简单  

  2. 不需要第三方的解析工具,利用java反射技术就可以完成任务  

  3. 编辑期可以验证正确性,查错变得容易  

  4. 提高开发效率  

缺点有:  

  1. 如果需要对于annotation进行修改,那么要重新编译整个工程  

  2. 业务类之间的关系不如XML配置那样容易把握。  

  3. 如果在程序中annotation比较多,直接影响代码质量,对于代码的简洁度有一定的影响

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值