Spring复习(三)IOC之注解

IDEA技巧
打开类或者接口
IDE支持使用“驼峰字符”前缀的方式来过滤查找列表,进而轻松完成搜索;比如:可
以使用“PoDI”来检索PodcastDaoImpl类)

Ctrl+N

1 通过注解配置bean

概述

相对于XML方式而言,通过注解的方式配置bean更加简洁和优雅,而且和MVC组件化开发的理念十分契合,是开发中常用的使用方式。

使用注解标识组件

①普通组件:@Component
标识一个受Spring IOC容器管理的组件
持久化层组件:@Respository
标识一个受Spring IOC容器管理的持久化层组件
业务逻辑层组件:@Service
标识一个受Spring IOC容器管理的业务逻辑层组件
表述层控制器组件:@Controller
标识一个受Spring IOC容器管理的表述层控制器组件
⑤组件命名规则
[1]默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id
[2]使用组件注解的value属性指定bean的id
[3]组件的作用域默认是单例的
[4]修改组件的id

@Controller("haha")

[5]修改组件作用域

@Scope(value="prototype")

注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以@Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。

扫描组件

组件被上述注解标识后还需要通过Spring进行扫描才能够侦测到。
①指定被扫描的package

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

②详细说明
[1]base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包及其子包中的所有类。
[2]当需要扫描多个包时可以使用逗号分隔。
[3]如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,示例:

<context:component-scan 
	base-package="com.tju.component" 
	resource-pattern="autowire/*.class"/>

[4]包含与排除
<context:include-filter>子节点表示要包含的目标类
注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。即:通过将use-default-filters属性设置为false,禁用默认过滤器(因为默认是全扫描进来的),然后扫描的就只是include-filter中的规则指定的组件了。
<context:exclude-filter>子节点表示要排除在外的目标类
●component-scan下可以拥有若干个include-filter和exclude-filter子节点

<context:component-scan base-package="edu.tju">
    <!--扫描的时候可以排除一些不必要的组件
    type="annotation" 指定排除规则,按照注解进行排除,标注了指定的注解不要
    expression="",注解的全类名

    type="assignable"  指定排除某个个具体的类,按照类排除
    expression="" 类的全类名
    -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
    <context:exclude-filter type="assignable" expression="edu.tju.controller.BookController"></context:exclude-filter>
</context:component-scan>
  <context:component-scan base-package="edu.tju" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"></context:include-filter>
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
    </context:component-scan>

使用注解将组建快速加入到容器中需要几步

1)给要添加的组件上标四个注解的任何一个
2)告诉spring自动扫描增加了注解的组件 依赖context名称空间
3)一定要导入aop包 支持加注解模式

2 组件装配(核心就是注解自动装配@Autowired)

①需求

Controller组件中往往需要用到Service组件的实例,Service组件中往往需要用到Repository组件的实例。Spring可以通过注解的方式帮我们实现属性的装配。

②实现依据

在指定要扫描的包时,<context:component-scan> 元素会自动注册一个bean的后置处理器:AutowiredAnnotationBeanPostProcessor的实例。该后置处理器可以自动装配标记了@Autowired、@Resource或@Inject注解的属性。

③@Autowired注解

[1]根据类型实现自动装配。
[2]构造器、普通字段(即使是非public)、一切具有参数的方法都可以应用@Autowired注解
[3]默认情况下,所有使用@Autowired注解的属性都需要被设置。当Spring找不到匹配的bean装配属性时,会抛出异常。
[4]若某一属性允许不被设置,可以设置@Autowired注解的required属性为 false
[5]默认情况下,当IOC容器里存在多个类型兼容的bean时,Spring会尝试匹配bean的id值是否与变量名相同,如果相同则进行装配。如果bean的id值不相同,通过类型的自动装配将无法工作。此时可以在@Qualifier注解里提供bean的名称。Spring甚至允许在方法的形参上标注@Qualifiter注解以指定注入bean的名称。
[6]@Autowired注解也可以应用在数组类型的属性上,此时Spring将会把所有匹配的bean进行自动装配。
[7]@Autowired注解也可以应用在集合属性上,此时Spring读取该集合的类型信息,然后自动装配所有与之兼容的bean。
[8]@Autowired注解用在java.util.Map上时,若该Map的键值为String,那么 Spring将自动装配与值类型兼容的bean作为值,并以bean的id值作为键。

④@Resource

@Resource注解要求提供一个bean名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为bean的名称。

⑤@Inject

@Inject和@Autowired注解一样也是按类型注入匹配的bean,但没有reqired属性。

<!--
    @Autowired原理
    @Autowired
    private BookService bookService;
    1)按照属性变量类型去容器中找到对应的组件 bookService = ioc.getBean(BookService.class)
        1)找到一个,就赋值
        2)没找到 抛异常
        3)找到多个
            1)按属性变量作为id继续匹配 假如找到按类型匹配的为以下容器:类BookService(id默认为bookservice),类BookServicExt(id默认为bookServicExt)
            与属性id匹配的容器是BookService(id为bookservice)
            2)如果没有匹配上 就报错
            本质是用属性变量名作为容器id去匹配的 类型为BookService的容器
            引出@Qualifier("要找的BookService的容器id")
                @Autowired
                private BookService bookService;
                1)找到装配
                2)找不到报错
     Autowired 标注的自动装配属性默认属性是一定装配上的,任何情况下没找到都是抛异常
     如果设置 @Autowired(required = false)找不到就设置null

      @Autowired自动装配的注解 @Resource @Inject
      @Autowired最强大 spring自己的注解
      @Resource j2ee java标准 扩展性更强

方法设置Autowired

/**
 * 方法上有@Autowired的话
 * 1)这个方法上也会在bean创建的时候运行
 * 2)这个方法上的每一个参数都会自动注入值
 * @param bookDao1
 * @param bookService
 */
@Autowired
public void hahaha(@Qualifier("bookDaoEx") BookDao bookDao1, BookService bookService){
    System.out.println("spring 运行了这个方法。。。。"+bookDao1+"====="+bookService);

}

3 Spring单元测试模块

步骤

1)导包 :spring 单元测试包spring test

  <dependency>
            <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
             <version>4.0.0.RELEASE</version>
         </dependency>

2)使用注解来指定Spring配置文件的位置( @ContextConfiguration),和加载spring单元测试模块类(@RunWith)(在测试类上)

区别

1)原来
private ApplicationContext IOC5 = new ClassPathXmlApplicationContext(“ApplicationContext.xml”);
使用的话是 BookController bookController = IOC5.getBean(BookController.class);
2)现在
现在直接导入注解指定配置文件,和spring单元测试模块
@Autowired
BookController bookController; //自动注入即可

用法

先使用注解指定配置文件位置

 @ContextConfiguration(locations = "classpath:ApplicationContext.xml")//使用它来指定配置文件的位置
  public class test {

在使用注解指定配置文件的位置

@RunWith(SpringJUnit4ClassRunner.class) //使用spring的单元测试模块 来执行标了@Test注解的测试方法
public class test {

4 泛型依赖注入

简介

Spring 4.x中可以为子类注入子类对应的泛型类型的成员变量的引用。

实现

[1]组件基类

//BaseRepository
public class BaseRepository<T> {
	
	public void save() {
		System.out.println("Saved by BaseRepository");
	}

}
//BaseService
public class BaseService<T> {
	
	@Autowired
	private BaseRepository<T> repository;
	
	public void add() {
		repository.save();
	}

}

[2]组件实体类
UserRepository

@Repository
public class UserRepository extends BaseRepository<User>{
	
	public void save() {
		System.out.println("Saved by UserRepository");
	}

}

UserService
@Service

public class UserService extends BaseService<User>{

}

[3]模型实体类

User
public class User {

}

[4]测试

ApplicationContext ioc = new ClassPathXmlApplicationContext("di.xml");

UserService us = (UserService) ioc.getBean("userService");

us.add();

执行结果
Saved by UserRepository

在这里插入图片描述

5 总结

IOC是一个容器,帮我们管理所有组件

1 依赖注入@Autowired:自动赋值

2 要使用Spring提供的更多IOC、AOP,必须加入到容器中

3 容器启动,创建所有单实例bean

4 autowired自动装配的时候,是从容器中找到符合要求的bean

5 ioc.getBean(“bookServlet”),也是从容器中找到这个bean

容器中包含了所有bean

容器到底是什么? 其实就是一个map

6 IDEA继承关系技巧

IntelliJ IDEA | 使用技巧—查看类的继承关系图

快捷键CTRL+H查看
在指定类右键查看diagram
也可以使用快捷键ctrl+alt+u,更快捷
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值