spring笔记四
使用注解完成bean对象的注册
类的注册
当你在类上面加上这些注解的时候就相当于把当前的类注册到ioc容器里面了,也就是你为这个类加上bean对象了。
有四个注解:
@Controller:控制器,推荐给控制器层的组件加这个注解,一般是在controller包下的组件
@Service:业务逻辑,推荐给业务逻辑层的组件加这个注解,一般是在service包下的组件
@Repository:给数据库层(也叫持久层,dao层)的组件加这个注解,一般是在dao包下的组件
@Component:给不属于以上几层的组件添加这个注解
注释可以随便加,这四个注释的作用是一样的,只是建议给各个层的组件加上相应的注解,毕竟都是给程序员看的,做到见注释知类的作用更好
修改bean的默认id
默认的id是首字母小写
如果要进行修改,就在你添加的那个注解后面加上(“你想要修改成的id”),比如@Service(“hahah”)
默认是单实例
如果要修改成多实例的话,就需要添加一个新的注解@Scope(value=“prototype”)就行了
告诉spring注解在哪
先添加context的依赖空间,再添加标签
<context:component-scan base-package=""></context:component-scan>
一定要导入Spring的aop的jar的包,因为只有导入了,才能进行扫描注解
扫描的时候除了
位置是在前面的标签里面的
<context:exclude-filter type expression />
例如:<context:exclude-filter type="annotation"expression=“org.springframework.stereotype.Service”/>
扫描的时候只扫描
前提是在context-component-scan标签里面的use-default-filters属性要为false该标签的规则和上面的一致
<context:include-filter type="annotation"expression=“org.springframework.stereotype.Service”/>
关于这两个标签的type属性的值问题
type=“annotation”:表示依赖于注解 expression表示注解的限定名
type=“assignable”:表示除了某个特定的类 expression表示类的限定名
type=“aspectj”:表示后面会学到的AspectJ的表达式
type=“custom”:表示自定义一个TypeFilter,定义那些类除外,那些不除外
type=“regex” :表示可以使用正则表达式的形式
使用注解进行自动注入
@Autowired
例如:
@Autowired
private Book book;
Spring就会在它的容器中找book这个bean对象进行相应的自动注入(当然你的book对象也是需要注册到ioc容器中的)
首先是根据type来找的,如果没有找到对应的bean对象的话就会抛异常,如果只是找到了一个的话就直接进行赋值了,如果资源类型的bean不止一个,默认是根据@Autowired注解标记的成员变量名作为id来进行寻找
required属性
这个注解还有一个属性是required,默认为true,必须要找到这个bean的对象,如果找不到的话就就会报错,如果修改为false的话,就表示即使没有找到这个bean的对象,他不会报错,甚至还会赋值一个null给它
这个注解还能够在方法上进行使用
下面是在这个注解的源码,可以看到能在构造器,方法,属性,注解上面都是能够进行使用
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
使用方法都是一样的,会对参数进行自动注入
@Qualifier注解
如果根据成员变量名作为id还是找不到bean,可以使用@Qualifier进行指定bean的id,例如:
@AutoWired
private Book bookExt;
当这个时候并没有这个属性名的id的bean对象的时候,你只需要加上一个@Qualifier(“book”)它就会找book这个类的bean的id进行赋值(这个注解的作用是让spring不必使用bookExt这个属性名的id作为寻找的东西,只需要直接根据注解的里面的进行查找)
需要注意的是如果写上了这个注解的话,那么里面的id就必须是找得到的,如果找不到的话还是会报错的
这个方法还能够在方法上面进行使用
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
这个是ElementType.Type的注释Class, interface (including annotation type), or enum declaration
使用方法都是一样的,一般是用于对方法参数的修改也就是注解是在方法参数前面使用的(如果针对的是方法的话)
@Resource和@Autowire
有两种注解都是表示的是自动注入:还有一种是@Inject这个注解(EJB)
@Resource 和 @Autowired:
前者是J2ee的,也就是Java自己的标准,这个从他的包的名称就能知道,后者是spring自己的注解,很强大
最主要的是,其实前者的拓展性更强,因为是Java的标准,如果你换了一个容器框架的话,这个注解还是能够识别而后者就不行了
使用spring单元测试
1,导包:spring单元测试包进行导入spring-test-5.1.2.RELEASE.jar
2,使用注解@ContextConfiguration(location="")来指定spring的配置文件的位置
3,再使用注解@RunWith指定使用哪一种驱动进行单元测试,默认是Junit
@RunWith(value=SpringJUnit4ClassRunner.class)这样的话spring的单元测试模块就会来执行标了@Test的注解的测试方法了,而以前的@Test的注解只能是由Junit来执行.然后就能够在单元测试类里面进行哪些@Autowired这些自动注入的注解的使用了,就是不用之前的创建容器和getBean方法了
泛型的依赖注入
三个dao包中的类:BaseDao,UserDao,BookDao
三个service包中的类:BaseService,BookService,UserService
设定BaseDao为抽象类,内部有抽象方法save
UserDao继承BaseDao,并且重写里面的方法save,添加注解@Repository
BookDao继承BaseDao,并重写方法save添加注解@Repository
BaseService里面添加变量private BookDao bookDao;并添加注解@Autowired完成自动注入,添加方法save,里面再用bookDao调用他的方法save
UserService继承BaseService,不重写方法save,添加注解@Service
BookService继承BaseService,不重写方法save,添加注解@Service
最后在写一个spring的单元测试类
当你直接用自动注入的方式进行调用UserService的时候,他会直接调用UserDao的save的方法
ioc部分总结
ioc是一个容器,帮我们管理所有的组件
1,依赖注入:@Autowired,进行自动赋值
2,某个组件要使用spring提供的更多(ioc aop)就必须加入到容器
体会
1,容器启动,创建所有单实例bean
2,autowired自动装配的时候,是从容器中找到这些符合要求的bean
3,ioc.getBean,也就是直接从ioc的容器中饭找到相对应的bean的对象
4,容器中包含了所有的bean对象
5,调试spring的源码,容器的底层其实就是一个map
6,这个map保存所有已经创建好的bean,并提供外界获取的功能
最后,规范注释,规范类名和方法名
这是看尚硅谷的雷丰阳雷老师的ssm讲解视频,万分感谢,如有不正,海旺指出,万分感谢