通过注解,创建bean
applicationContext.xml
文件
<!-- 通过注解,分别创建DAO,Servlice,Controller(控制器:控制网站跳转逻辑servlet) -->
<!-- 通过给bean添加某些注解,可以快速将bean添加到ioc容器中
在某个类上添加任何一个注解都能快速将这个组件加入到ioc容器中
Spring有四个注解:
@Controller:推荐给控制器层(servlet包下的这些)
@Servlce:业务逻辑,如:BookService
@Repository:给数据库层(持久层,dao层)的组件添加这个注解
@Compontent:给不属于以上几层的添加
Spring底层不会去验证这个注解,各自层加各自的注解,Spring不会
-->
<!--
步骤如下:
1.加注解
2.告诉Spring,自动扫描这个注解的组件,依赖context名称空间
3.一定要导入aop包,它支持注解
context:component-scan(自动扫描组件)
base-package(扫描指定的基础包,包以及包下的所有注解的类,自动扫描进ioc容器)
-->
<context:component-scan base-package="com.daq">
</context:component-scan>
- 测试
public class IocTest {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("applicationContext.xml");
//使用注解加入到容器中的组件,和使用配置加入到容器中是一样的
1.组件的id。默认就是组件的类名的首字母小写
也可以在注解里面自定义:
@Respority("bookdaohaha"),这样获取的时候就要
2.组件的作用域,默认就是单例的。
@Test
public void test(){
Object bean = ioc.getBean("bookDao");
Object bean2 = ioc.getBean("bookDao");
System.out.println(bean==bean2);//结果为true
}
}
- 注解并不能干所有的事,比如说,想要把引入的包中的某个类加到容器中,不能在引入的包中加注解,那么这个时候,就要手动配置bean了,所以,注解与bean相结合,就可以把任意的类加入到容器中。
扫描指定类
<!-- 使用context: exclude-filter指定扫描包时不包含的类 -->
<!-- 扫描的时候可以排除一些不要的组件
type="annotation"按照注解进行排除,标注了指定注解的类不要。
expression="" 注解的全类名
type="annotation"按照类进行排除,指定的类不要。
expression="" 类的全类名
-->
<context:component-scan base-package="com.daq">
<context:exclude-filter type="annotation" expression="com.daq.service.BookService"/>
</context:component-scan>
<!-- 使用context: include-filter指定扫描包时不包含的类,使用时要禁用默认属性:
use-default-filters="false"
type="annotation"按照注解进行排除,标注了指定注解的类不要。
expression="" 注解的全类名
type="annotation"按照类进行排除,指定的类不要。
expression="" 类的全类名
-->
<context:component-scan base-package="com.daq" use-default-filters="false">
<context:include-filter type="annotation" expression="com.daq.service.BookService"/>
</context:component-scan>
DL(依赖查找)
- DL已经被抛弃,因为它需要用户自己去使用API进行查找资源和组装对象,具有侵略性。
DI(依赖注入)
- DI是Spring使用的方式,容器负责组件的安装。
@Autowired
注解:Spring会自动为这个属性赋值,一定是去容器中找到这个属性对应的组件。自动注入值只是对引用而言。@Autowired
原理:
private BookService bookService;
- 先按照类型去容器中找到对应的组件
bookService = ioc.getBean(BookService.class);
①. 找到一个,就直接赋值。
②. 没找到:抛异常
③. 找到多个,就按照变量名id继续匹配 :bookService,bookServiceExt。
如果没有匹配上,(是因为我们用变量名作为id继续匹配,没有那个变量名,就匹配不上)
这时候,就要用到@Qualifier("")
指定一个名作为id、 - 由此发现:
@Autowired
找得到就装配,找不到就拉到。 @Autowired
注解的require的属性指定某个属性允许不被设置。这样就不会被强行装上。
- 方法上有
@Autowired
注解那么
①这个方法也会在bean创建的时候自动运行。
②这个方法上的每一个参数都会自动注入值。
Autowired和Resource的区别
-
@Autowired
,@Resource
,@Inject
都是自动装配的意思。
①@Autowired
:最强大,是Spring自己的注解。
②@Resource
:j2ee,java的标准,功能一般。
③@Inject
:EJB -
区别:
①@Autowired
离开Spring就没法用。
②@Resource
扩展性强,因为他是java的标准,如果切换成另外一个容器框架,@Resource
还是被支持的。
Spring的单元测试
/*
* Spring的单元测试
* 1.导包
* 2.@ContextConfiguration(locations="")指定Spring配置文件的位置
* 3.@RunWith指定哪种驱动进行单元测试,默认就是junit
* @RunWith(SpringJUnit4ClassRunner.class)
* 使用Spring的单元测试模块来执行了@Test注解的测试方法
* 以前的@Test注解只是由Junit
* 好处:我们不用ioc.getBean()获取组件,直接用Autowired组件,Spring为我们自动装配
*/
@ContextConfiguration(locations="classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class IocTest {
// ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext ioc;
@Autowired
BookServlet bookServlet;
@Test
public void test03(){
System.out.println(bookServlet);
}
泛型依赖注入
- 泛型依赖注入原理
- 带泛型的父类类型
//父类的类型:com.atguigu.service.BaseService
//带泛型的父类类型:com.atguigu.service.BaseService<com.atguigu.bean.Book>
//Spring中可以使用带泛型的父类类型来确定这个子类的类型
System.out.println(bookService.getClass().getGenericSuperclass());