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,更快捷