线上实训day02(一)——Spring的自动装配

什么是自动装配:

  • 自动装配:表现为可以自动注入值,而不需要在xml文件中通过set方式或构造方法来进行注入。

一、autowire属性(标签)

  • 在xml配置文件中,可以在bean元素中使用autowire属性来帮助自动注入依赖对象,掌握三种:
  1. No:禁用自动装配,默认值;
  2. byName:根据属性名自动装配;比如说类Computer有个属性printer,指定其autowire属性为byName后,Spring IoC容器会在配置文件中查找id/name属性为printer的bean,然后使用Seter方法为其注入。
  3. byType:如果容器中存中一个指定属性类型相同的bean,那么将与该属性自动装配;。比如类Computer有个属性printer,类型为Printer,那么,指定其autowire属性为byType后,Spring IoC容器会查找Class属性为Printer的bean,使用Seter方法为其注入
  1. byType的讲解:

项目目录——>创建接口——>创建实现类——创建Service类——>配置文件——>测试

import day02.a.dao.IUserDao;

public class UserService {
	private IUserDao userdao;

	public void setUserDao(IUserDao userdao) {
		this.userdao = userdao;
		System.out.println("11111");
	}

	public void reg() {
		System.out.println("UserService.reg()");
		userdao.insert();
	}
}
<bean id="userDao" class="day02.a.dao.UserDaoImpl"></bean>
	<bean id="userService" class="day02.a.service.UserService"
		autowire="byType">

测试:

public class Test {
	public static void main(String[] args) {
		// 读取配置文件
		String file = "day02/a/resources/applicationContext.xml";
		AbstractApplicationContext ac = new ClassPathXmlApplicationContext(file);
		// 获取bean对象:UserService
		UserService service = ac.getBean("userService", UserService.class);
		// 执行业务:reg()
		service.reg();
		// 释放资源
		ac.close();
	}
}

j结果: 

但是:如果类型匹配到2个或多个会导致程序崩溃!!这个时候可以用byName

  1. byName的讲解

总结:

  1. byName据属性名完成自动装配,要求在xml文件中存在相同名称的配置,如果没有对应的将不会自动装配,也不报错。当指定了该属性的时候,Spring会根据setXXX方法查找对应的bean,然后自动注入,执行setXXX方法。
  2. byType:根据属性的类型完成自动装配,要求在xml文件存在与属性的类型相同的bean配置,这样的做法对于id没有要求,注意:如果类型匹配到2个或多个会导致程序崩溃!!

二、组件扫描

  1. 什么是组件扫描:可以配置spring对指定的包进行扫描,使得在利用spring开发时,不必再用spring的xml文件中对bean进行配置!spring扫描指定的包时,直接对扫描得到的Bean进行管理!对于开发者而言,最直接的表现就是不必再配置spring的xml文件中的节点。
  2. 为什么使用组件扫描:相关的配置均会体现在对应的Java类中,表现的更加直观,易于调整。
  3. 组件扫描关键点:

(1)指定类扫描路径:使用组件扫描,首先需要在xml配置中指定扫描父级package的路径;

(2)指定扫描路径后,并不是该路径下所有的组件类都扫描到容器中,只有组件类定义前面有以下标记时,才会扫描到spring容器:

@Component:通用注解

@Name:通用注解

@Repository:持久化层组件注解

@Service:业务层组件注解

@Controller:控制层组件注解

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

案例:

import org.springframework.stereotype.Component;

@Component
public class User {
	public User() {
		System.out.println("User()");
	}
}

配置文件指定父包(要能访问全所需要的东西):

public class Test {
	public static void main(String[] args) {
		// 读取配置文件
		String file = "day02/b/resources/applicationContext.xml";
		AbstractApplicationContext ac = new ClassPathXmlApplicationContext(file);
		// 获取bean对象:UserService
		User user = ac.getBean("user", User.class);
		System.out.println(user);
		// 释放资源
		ac.close();
	}
}

测试: 

小结:当spring扫描到User类后,会自动根据类名决定生成的id为user,即类名的首字母小写,就是id。如果后边配置了id,则必须使用配的id获取实例: 例如@Component(“U”);

 

三、使用注解实现自动装配

——传统的Spring做法是使用.xml文件来对bean进行注入等方法,这么做有两个缺点:

1、如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大;如果按需求分开.xml文件,那么.xml文件又会非常多。总之这将导致配置文件的可读性与可维护性变得很低

2、在开发中在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率

为了解决这两个问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。

(一)@Autowired和Qualifier的组合

1、@Autowired顾名思义,就是自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property。

2、实现类就是有多个该怎么办?此时可以使用@Qualifier注解——Qualifier注解括号()里面的应当是bean的id名

案例:

目录结构:     IUserDao接口:

UserDaoImpl类:

import org.springframework.stereotype.Component;

@Component("userDao")
public class UserDaoImpl implements IUserDao {

	public void insert() {
		System.out.println("UserDapImpl.insert()");
	}

}

IUserService接口: 

UserServiceImpl实现类:

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import day02.c.dao.IUserDao;

@Component("userService")
public class UserServiceImpl implements IUserService {
	// 自动装配
	@Autowired
	@Qualifier("userDao")

	private IUserDao userDao;

	public void reg() {
		System.out.println("UserServiceImpl.reg()");
		userDao.insert();
	}

	// 不走set方法:
	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
		System.out.println("userServiceImpl-->arg0:" + userDao);
	}

}

配置文件:

测试:

结果:可以看出没有执行set方法

小结:

     1)这种组合方式不仅仅可以用于基于set的注入,也可以用于基于构造方法的注入!并且,这种组合还可以用于需要注解的属性。

    2注解属性的优势在于简单易用,而注解方法的优势在于在方法中可以编写其他代码!

 

(二)@Resource

1、@Resource只能处理setter注入,且大部分情况都是setter注入。

2、@Resource分析整个过程

 对如下分析:

    @Resource

  private BasicDataSource ds;

  1)当启动spring容器的时候,spring容器加载了配置文件

  2)在spring配置文件中,只要遇到bean的配置,就会为该bean创建对象。

  3)在纳入spring容器的范围内查找所有的bean,看哪些bean的属性或方法上加有@Resource

  4)找到@Resource注解以后:

   (1)判断@Resource后面的“()” 有没有内容。没有内容则——则会让属性的名称和spring中ID的值做匹配,如果匹配成功则赋值。如果匹配不成功,则会按照类型进行匹配,如果匹配不成功则报错。

  (2)如果有name属性,则会按照name属性的值和spring的bean中的id进行匹配,匹配成功,则赋值,不成功则报错。

——指定了name或者type则根据指定的类型去匹配bean;

——指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错

 

5)@Autowired和@Resource两个注解的区别:

 (1)@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配

(2)@Autowired是Spring的注解,@Resource是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了

Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合。

 

总结:

       @Autowired 根据类型注入

       @Resource 默认根据名字注入,其次根据类型搜索

       @Autowired @Qualifier("userDao") 两个结合起来可以根据名字和类型注入。

 

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值