文章目录
SpringIOC学习
1.Demo
- 手动引入包Spring
- 配置
- 使用
2.关于spring IOC
Spring IOC是由依赖注入实现的
依赖注入方式:set方法注入,构造方法注入,字段注入
注入类型:值类型注入:八大基本类型;引用类型注入:依赖对象注入
容器的实现
-
概述
ApplicationContext:容器每次启动时就会创建容器中配置的所有对象
beanfactory接口实现类的容器,特点是每次获得对象时才会创建。
Web中使用ApplicationContext -
ApplicationContext:
-
从类路径加载配置文件ClassPathXmlApplicationContext
-
从硬盘绝对路径下加载配置文件FileSystemXmlApplicationContext
-
设置容器它的周期 与servletcontext生命周期(application所在的对象,在容器中只存在一份,随着项目创建而创建,随着项目销毁而销毁)相同。
我们之前的获取是通过前面的路径加载spring配置文件,然后创建获取容器,但是实际上这样是不好的,我们整个项目很大时,不可能每次重新创建容器,容器应该只有一个,所以需要像servletcontext容器一样生命周期。
首先导入spring-web-***包并 配置监听器
然后指定spring配置文件路径
此时就可以在application域可以获得spring容器:过程是首先servletcontext在启动时会加载配置文件将容器保存在servletcontext中,所以先要获取servletcontext再获取spring容器
3.spring配置文件实现注入
- Bean
- Bean元素:使用该元素描述需要spring容器管理的对象
- class属性:被管理对象完整类名
- name属性:给对象取名字,获取对象时可以根据该名称获得对象。可以重复,可以使用特殊字符
- id属性:与name一样。但是名字不能重复,不能使用特殊字符
- scope属性:singleton(默认):单例对象,生成一个实例。Prototype(多例原型):每次再获得才会创建,创建都是新对象。Request:web环境下.对象与request生命周期一致。Session:web环境下,与session声明周期一致。
- 生命周期属性:
创建方法
-
配置
实现:在创建时调用init,在销毁后调用destroy -
导入其他配置文件
这样为了方便配置文件管理,模块化配置文件,最终应该只需要导入一个配置文件就好了 -
Spring属性注入
- Set方法注入(最重要)
- 构造函数注入(重要)
另外经过测试,如果没有index,当出现顺序不同的参数时,会执行在类中最后一个写的构造函数
3. P名称空间注入(了解)
首先引入p名称空间
xmlns:p=http://www.springframework.org/schema/p
其次配置
对象类型使用的p:属性名-ref=”bean名称”,比如p:car-ref=”car”
4. Spel注入(了解)
Spel:spring expression language。形式#{user.name},是一种基于已经注入了的属性来使用的。即基于前面几种注入来实现的。
- 复杂类型的注入(list,map,set,数组 …)
List,arry,set这些注入都差不多,分为多个值一个值的写法
Map有点区别,但是和properties差不多,只是标签换一下
Prop
如何创建对象
- 空参构造函数创建
- 静态工厂创建(了解)
工厂类与方法
配置
创建
- 实例工厂创建/动态工厂(了解)
创建方法
配置:由于非静态方法不能重新调用,所以需要用bean实例化
使用
使用注解代替配置文件
-
首先导入spring-context约束 应该不是必要的,为了写的时候有提示方便。导入规则首先在Windowpreferences-搜索catalog选择xml catalog然后找到本地的catalogadd修改key完成,然后到xml选择design视图,然后bean右键编辑namespace然后add找到刚才设置的key编辑namespace(去掉最后),编辑prefix为namespace现在最后那个如:Context(这里不重复就好)。
当然前面是在没网情况下,有网时只需要添加约束就好(我认为)。 -
开启注解配置
-
装配值使用@Value注解:
-
装配对象有两种,Autowired和@Resource,@Resource可以直接指定bean名字,@autowried需要配合才能指定
-
整合unit测试单元
为什么要整合呢? -
方便。举个栗子,当我们使用spring配置文件创建容器时只能ClassPathXmlApplicationContext或者硬盘加载创建,总之特别麻烦。单元测试可以为我们创建好容器,等功能。
先引入spring-test包
然后
实例:
Car
测试单元
Spring aop学习
1.Aop思想,概念,原理。(了解)
Spring原理:动态代理
关于动态代理可以查看这篇博客:https://www.cnblogs.com/maohuidong/p/7992894.html
动态代理
栗子
目标类(UserServiceImpl)必须是由继承了相应接口(Userserivce)的,且proxy创建代理实例只能给interface声明的引用,推测该实现其实是通过实现另外一个类(暂且称为ProxyUserServiceImpl)继承了该接口(UserService),所以导致不能直接赋值给UserServiceImpl声明的引用
使用
Cglib代理
使用
使用2:
UserserviceImpl us来接收并使用
**两个代理主要区别:cglib代理对象继承了被代理对象或者是直接对对象方法进行代理(具体之后看了源码补充),所以他可以使用对象和接口声明的引用来指向代理对象。但是动态代理与被代理对象推测应该是实现了同一个接口,所以只能使用接口接收对象 **
2. aop中的名词解释
- Joinpoint(连接点):目标对象中,所有可以增强的方法
- Pointcut(切入点):目标对象中,已经增强的方法。
- Advice(通知/增强):需要增强的代码
- Target(目标对象):被代理对象
- Weaving(织入):将通知应用带切入点的过程
- Proxy(代理):将通知织入到目标对象后,形成代理对象。
- Aspect(切面):切入点+通知
3.spring使用aop
-
导包
-
实现
首先是配置文件,该配置文件在类路径下面,也就是src开始的地方,名字什么的随便,需要注意的就是这里包含了前面IOC容器的思想。是结合在一起使用的。另外下面都是通过配置文件实现的IOC和aop,之后还会涉及到注解反射设计的实现,那将更加方便。
其次是涉及到的通知类,也就是把加强的方法放到统一的一个类中管理,需要注意的是环绕通知方法需要参数。
需要代理的目标类
使用
理解:我们只需要写好配置文件和需要代理的目标对象,以及需要加强在的目标对象方法(after,before…通知类管理.),这些方法spring会通过读取配置自动代理到对应的方法。我们通过autowired得到的userservice是代理对象,它是spring为我们生成的。而且ServiceImpl继承了接口时,接受的变量声明必须是接口定义的*
但是当我们没有继承接口如下
直接用UserServiceImpl来接收,推测可能是两种情况他在是实现时的差别,具体之后看了再细说。
另外,实验证明目标代理对象必须在容器中如下:
这样将无法在调用时加强add方法,推想因为spring的aop是通过IOC实现的,它在容器中抛出时的对象才会像cglib代理那样继承了userservice接口,所以它抛出的对象也不能用UserserviceImpl类的对象接收,因为他们只是继承了同一个接口而已,是不同的类。但是在配置文件中将userserviceimpl的bean声明出来是必要的,因为在spring aop自动进行配置时肯定需要从容器中获得目标对象,然后加强方法,具体可以参考动态代理和cglib代理的实现。当然这些知识暂时猜测,具体可以看源码!
4spring注解实现aop
首先是配置文件,开启注解和扫描
其次是响应的注解使得IOC容器目标对象和切面类放到容器,然后切面类要加@Aspect表明切面类,然后要指定前置通知,后置通知等,并且要指定通知的切入点
** 但是这里有个问题,当我们修改需要代理的类是要改很多代码,可以加入@pointcut注解,来简化我们操作。这样我们只需要修改一次,此时pc方法只是个标记方法 **
还可以像下面一样,专门用一个类保存标记,之后使用的通知都直接通过包的方式制定切入点
另外标记也可以用注解来实现
首先是注解声明
标记方法
这样我们可以将注解放在想要加强的方法上,可以灵活的指定
这里只有add方法注解了,所以只有add加强,其他均没有,另外,这个类也也同前面一样需要在IOC容器中创建,但是这个类就不是必须要一个接口了(如没有userservice也可以)。