Spring笔记
IOC(控制反转) 概念原理
也叫DI(依赖注入)
1、什么是IOC
IOC中文就是控制反转,但这个晦涩难懂,所以有个新词代替这个词就是依赖注入,就是,调用类对某个接口实现类的依赖调用由第三方(Spring的容器)来实现,以移除调用类对某一接口实现类的依赖,从而减少代码的耦合度。
1)控制反转,把对象创建和对象之间的调用过程交给spring进行管理
2)使用ioc目的:降低耦合度
3)做入门案例是ioc实现
2 、ioc底层原理
1)xml解析、工厂模式、反射
3、图解ioc底层原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MN968Ioa-1661344646769)(D:\工具\typora\images\image-20220703111021683.png)]
原始方式 :userservice调用userdao的方法是通过创建userdao的对象 通过对象调用方法
虽然也能调用,但是耦合度太高了,userdao变了userservice也要变
方法一:工厂模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VqwxJMEz-1661344646771)(D:\工具\typora\images\image-20220703111837918.png)]
service和dao做了解耦
但是工厂和dao仍有耦合
耦合无法降为0 只能尽量最低 但是这里不是最低
方法二:ioc (xml解析 工程模式 反射)
第一步xml配置文件 配置创建的对象
第二步 有service类和dao类 创建工厂类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6iScZjn-1661344646771)(D:\工具\typora\images\image-20220703112654202.png)]
进一步降低耦合度
ioc(接口)
1)ioc思想基于ioc容器完成 ioc容器底层就是对象工厂
2)spring提供ioc容器实现两种方式(两个接口)
(1)BeanFactory:ioc容器最基本实现方式,是spring内部使用接口,不提供开发人员进行使用
*
加载配置文件的时候不会创建对象,在获取(使用)的时候才创建对象
(2)ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
*
在加载配置文件的时候就会把在配置文件中的对象进行创建
3)ApplicationContext接口有实现类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VXSxQ8FU-1661344646771)(D:\工具\typora\images\image-20220703114224951.png)]
(1)FileSystenXmlApplicationContext
(2)ClassPathXmlApplicationContext
IOC操作Bean管理(概念)
1、什么是Bean管理,Bean管理指的是两个操作
1)spring创建对象
2)spring注入属性
2、Bean管理操作有两种方式
1)基于xml配置文件方式实现
2)基于注解方式实现
IOC操作Bean管理(基于xml方式)
1、基于xml方式创建对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ACskJkYw-1661344646772)(D:\工具\typora\images\image-20220703115205490.png)]
1)在spring配置文件中使用bean标签,标签内添加对应属性,就可以实现对象创建
2)在bean标签中有很多属性,介绍常用属性
*id属性:给对象取个标识(别名)
*class属性:类全路径(包类路径)
还有name属性但已经不怎么用,常用id属性
3)创建对象的时候,默认也是执行
无参数
构造方法
2、基于xml方式注入属性(依赖注入)
(1)
DI:依赖注入,就是注入属性
DI是IOC中一种具体实现,表示依赖注入,也就是注入属性,但是注入属性是在创建对象的基础上完成
第一种注入方式:使用set 注入
1、创建类和对应属性的set方法
2、在spring配置文件配置对象创建,配置属性注入
<bean id="demo" class="Pojo.Demo">
<!--使用property完成属性注入-->
<property name="bname" value="java"></property>
</bean>
第二种注入方式:使用有参数的构造进行注入
1、创建类,定义属性,创建属性对应有参数构造方法
2、在spring配置文件中进行配置
使用标签配置
在这里若javabean中没有无参构造会报错,因为默认用无参构造的方法创建对象
第三种注入方式:p名称空间注入(底层还是set方式注入)
1、使用p名称空间注入,可以简化基于xml配置方式
第一步:添加p名称空间在配置文件中
xmlns:p="http://www.springframework.org/schema/p"
第二步:进行属性注入,在bean标签里面进行操作
<!--p名称空间-->
<bean id="demo" class="Pojo.Demo" p:bname="math">
</bean>
3、xml注入其他类型属性
1、字面量:
字面量(literal)是用于表达源代码中一个固定值的表示法
1)null值
使用null标签
<!--set方法进行注入-->
<bean id="demo" class="Pojo.Demo">
<!--使用property完成属性注入-->
<property name="bname" >
<null></null>
</property>
</bean>
2)属性值包含特殊符号
1、 把<>转义
用<;>;
2、把特殊符号内容写到CDATA
<bean id="demo" class="Pojo.Demo">
<!--使用property完成属性注入-->
<property name="bname" >
<value><![CDATA[<<南京>>]]></value>
</property>
</bean>
4、注入属性-外部bean
1)创建两个类service类和dao类
2)在service调用dao里面的方法
原始方法:在service类中创建dao对象,用对象调用方法
spring方法:spring配置文件中进行配置
<bean id="dao" class="dao.Daot1">
<!--ref:Demo对象bean标签id值 注入外部bean-->
<property name="demo" ref="demo"></property>
</bean>
<bean id="demo" class="Pojo.Demo">
<property name="bname" value="javabook"></property>
</bean>
5、注入属性-内部bean和级联赋值
1)一对多关系:部门和员工
一个部门有多个员工,一个员工属于一个部门
2)在实体类之间表示一对多关系
员工表示所属部门,使用对象类型属性进行表示
內部bean如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V2hgvhNC-1661344646773)(D:/工具/typora/images/image-20220704093718433.png)]
级联赋值的写法如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0UvDxd3d-1661344646773)(D:/工具/typora/images/image-20220704094330393.png)]
级联赋值第二种写法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2hbHOSru-1661344646773)(D:/工具/typora/images/image-20220704094747463.png)]
结果为技术部
注:dept中属性要有get方法,不然取不到值会爆红
6、xml注入集合属性
1、注入数组类型属性
2、注入List集合类型属性
3、注入Map集合类型属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5i70aPfW-1661344646774)(D:/工具/typora/images/image-20220704101342530.png)]
注入集合类型的
一些细节问题:
1、在集合中设置对象类型的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uUb62uH4-1661344646775)(D:/工具/typora/images/image-20220704104256214.png)]
2、把集合注入部分提取出来
1)在spring配置文件中引入名称空间util
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i6dHwiYn-1661344646775)(D:/工具/typora/images/image-20220704105424436.png)]
2)将公共部分注入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IjTc25Th-1661344646776)(D:/工具/typora/images/image-20220704105449473.png)]
7、FactoryBean和普通Bean
1、spring有两种类型bean,一种是普通bean,一种是工厂bean(FactoryBean)
普通bean:在spring配置文件中定义的bean类型就是返回类型
工厂bean:在配置文件中定义Bean类型可以和返回类型不一样
第一步 创建类,让类作为工厂bean,实现接口FactoryBean
第二部 实现接口里面的方法,在实现的方法中定义返回的bean类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Po47Vog6-1661344646776)(D:/工具/typora/images/image-20220704113912797.png)]
可以通过实现FactoryBean接口
重写getobject方法来决定返回类型
8、Bean的作用域和生命周期
作用域:
1、在spring里面,设置创建bean实例是单实例还是多实例
2、在spring里面,默认情况下,bean是单实例对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QOHYTKnQ-1661344646776)(D:/工具/typora/images/image-20220704114351002.png)]
两个地址相同
3、如何设置单实例还是多实例
1)在spring配置文件bean标签里面有属性(scope)用于设置
2)scope属性值:
第一个值也就是
默认值
,singleton,表示单实例对象
第二个值是prototype,表示多实例对象
3)singleton和prototype区别
第一 singleton单实例,prototype多实例
第二 设置scope值是
singleton
时候,加载spring配置文件时候就会创建单实例对象
设置scope值是
prototype
的时候,不是在加载spring配置文件的时候创建对象,而是在调用getbean方法的时候才创建多实例对象
生命周期
:
1、从对象创建到对象销毁的过程
2、
bean生命周期
1)通过构造器创建bean实例(无参数构造)
2)为bean的属性设置值和对其他bean的引用(调用set方法)
3)调用bean的初始化的方法(需要进行配置 bean标签中的init-method)
4)bean可以使用了(对象获取到bean了)
5)当容器关闭的时候,调用bean的销毁的方法(需要进行配置销毁的方法 bean标签中的destroy-method)
context.close()执行后 bean会销毁,从而执行destroymethod方法
3、演示bean的生命周期
第一步 执行无参数构造创建bean实例
第二步 调用set方法设置属性值
第三步 执行初始化的方法
第四步 获取创建bean实例对象
第五步 执行销毁的方法
4、添加bean的后置处理器后,bean生命周期有七步
注:这里后置处理器要自己添加,方法是实现BeanPostProcessor接口
1)通过构造器创建bean实例(无参数构造)
2)为bean的属性设置值和对其他bean的引用(调用set方法)
3)把bean实例传递bean后置处理器的方法postProcessBeforeInitialization()
4)调用bean的初始化的方法(需要进行配置 bean标签中的init-method)
5)把bean实例传递给bean后置处理器的方法postProcessBeforeInitialization()
6)bean可以使用了(对象获取到bean了)
7)当容器关闭的时候,调用bean的销毁的方法(需要进行配置销毁的方法 bean标签中的destroy-method)
9、xml自动装配
1、什么是自动装配
1)根据指定装配规则(1:属性名称或2:属性类型),spring自动将匹配的属性值进行注入
2、自动装配实现过程
bean标签属性autowire,配置自动装配
autowire常用值有两个
byname(根据属性名称注入):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ImwcOzrm-1661344646777)(D:/工具/typora/images/image-20220704170326232.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1IQFPw0f-1661344646777)(D:/工具/typora/images/image-20220704165940584.png)]
特点:注入值bean的id值和类属性名称一致才能自动装配
bytype (根据属性类型注入):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5aTFIoZM-1661344646778)(D:/工具/typora/images/image-20220704170040768.png)]
特点:名称不在要求相同,但是当目标类型有两个或多个对象时,无法确定用哪一个注入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uUMoRh2L-1661344646778)(D:/工具/typora/images/image-20220704170241780.png)]
开发中xml自动装配用的不多,通常用注解实现
10、xml外部属性文件
1、直接配置数据库信息
1)配置德鲁伊连接池
2)引入德鲁伊连接池依赖jar包
2、引入外部属性文件配置数据库连接池
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iLuZNPjo-1661344646778)(D:/工具/typora/images/image-20220705100853555.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r1PNPYMm-1661344646779)(D:/工具/typora/images/image-20220705110132331.png)]
配置名称空间 context
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s5huhZ3z-1661344646779)(D:/工具/typora/images/image-20220705102057088.png)]
引入外部文件 ${配置文件中的变量名}
基于注解操作Bean
1、什么是注解
1)注解是代码特殊标记,格式@注解名称(属性名称=属性值,属性名称=属性值…)
2)使用注解,注解作用在类上面,方法上面,属性上面
3)使用注解目的:简化xml配置
2、spring针对Bean管理中创建对象提供注解
1)@Component
2)@Service
3)@Controller
4)@Repository
通常把service用在 service层,把controller用在web层,把repository用在dao层,四个功能相同,混合用也没错,主要是为了区分当前组件所扮演的角色
3、基于注解方式实现对象创建
第一步:引入AOP依赖
第二步:开启组件扫描
引入context名称空间
添加context标签
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZlJ17gmd-1661344646779)(D:/工具/typora/images/image-20220705105104917.png)]
也可以扫描上层路径
第三步:创建类,在类上面添加创建对象注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XzeGBKWO-1661344646780)(D:/工具/typora/images/image-20220705105643671.png)]
4、开启组件扫面细节配置
扫描目标为包时,包中所有类都会被扫描
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AEvaicwo-1661344646780)(D:/工具/typora/images/image-20220705112257252.png)]
可以自由设置哪些内容被扫描
默认过滤器表示扫描包下所有类
不使用默认过滤器,使用context:include-filter标签,表示只扫描特定的注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JevYtouq-1661344646781)(D:/工具/typora/images/image-20220705112157599.png)]
如图表示只扫描带service注解的类
使用默认过滤器,使用context:exclude-filter标签表示不扫描特定的类
5、基于注解方式实现属性注入
1)@AutoWired(多用于对象类型属性):根据
属性类型
进行自动装配
因为是根据属性类型,所以该注解要加在目标属性上面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WNsU09lI-1661344646781)(D:/工具/typora/images/image-20220705114617528.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pl0P8JIn-1661344646781)(D:/工具/typora/images/image-20220705114645801.png)]
2)@Qualier(多用于对象类型属性):根据
属性名称
进行注入
@Qualifier注解的使用,和上面@AutoWired一起使用
当有多个部门时,不知道员工是哪个部门的,所以用此注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ja5Zuuc6-1661344646782)(D:/工具/typora/images/image-20220705115304251.png)]
指明具体用哪一个对象
3)@Resource(通常用于对象类型属性):可以根据类型注入,可以根据名称注入
@Resource不是spring包中的,spring不推荐用
如图 指明name时为根据名称注入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iZNh0ErW-1661344646782)(D:/工具/typora/images/image-20220705120639698.png)]
只写注释@Resource时为根据类型注入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4YnaGH1G-1661344646783)(D:/工具/typora/images/image-20220705120754065.png)]
4)@Value:注入普通类型属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIa4jaQ0-1661344646783)(D:/工具/typora/images/image-20220705120948614.png)]
@Value(value=“ ”)
括号内value为属性值
6、完全注解开发(即不使用xml)
1)创建配置类,替代xml配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-euIFQnZa-1661344646783)(D:/工具/typora/images/image-20220705160607369.png)]
2)加载配置类
由xml改为配置类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AO9UNv50-1661344646784)(D:/工具/typora/images/image-20220705160900508.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i62hqTTn-1661344646784)(D:/工具/typora/images/image-20220705161033602.png)]
AOP概念原理
1、什么是AOP
1)AOP为Aspect Oriented Programming的缩写,意为面向切片编程,利用AOP可以对业务逻辑的各个部分进行
隔离
,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WpYlBrsb-1661344646785)(D:/工具/typora/images/image-20220706095106606.png)]
AOP的思想:只需要将需求设计成模块加入原有系统,当有一天不再需要此需求时,也只需要删掉此模块,降低了耦合度
通俗描述:不通过修改源码的方式,在主干功能里面添加新功能
2、AOP 底层原理
1、AOP底层使用动态代理
1)动态代理中有两种情况
第一种:有接口的情况,使用JDK动态代理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oq0ajzkL-1661344646785)(D:/工具/typora/images/image-20220706100951792.png)]
创建接口实现类的代理对象,增强类的方法
第二种:没有接口的情况,使用CGLIB动态代理
原始方法:创建新类继承原始类,通过重写父类方法增强功能
CGLIB:创建当前类子类的代理对象,增强类的方法
2)jdk实现动态代理
使用proxy类里面的方法创建代理对象
1、调用newProxyInstance方法
方法有三个参数:
第一个参数:类加载器
第二个参数:增强方法所在类,这个类实现的接口,支持多个接口
第三个参数: InvocationHandler接口,创建代理对象,写增强的方法
2、JDK动态代理代码
1)创建接口,定义方法
2)创建接口实现类,实现方法
3、AOP术语
1、连接点
在一个类中,类的哪些方法可以被增强,这些方法被称为连接点
2、切入点
实际被真正增强的方法,称为切入点
例如类中有三个方法,只有一个被增强,被增强的这个称为切入点
3、通知(增强)
(1)实际增强的逻辑部分称为通知(增强)
(2)通知有多种类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WoXs1nM1-1661344646785)(D:/工具/typora/images/image-20220706195608926.png)]
*前置通知:在切入点之前执行
@Before
*后置(返回)通知:在切入点之后执行
@AfterReturning 表示在方法返回值之后执行
*环绕通知:在方法前后都执行
@Round
*异常通知:当方法出现异常则执行
@AfterThrowing
*最终通知:类似try-catch中的finally 不管有没有异常都会执行
@After 表示在方法执行完后执行
4、切面
切面是动作
(1)把通知应用到切入点过程就称为切面
4、AOP操作
1、spring框架一般基于AspectJ实现AOP操作
(1)什么是AspectJ
AspectJ不是spring组成部分,独立AOP框架,一般把AspectJ和spring一起使用,进行AOP操作
(2)基于AspectJ实现AOP
1、基于xml配置文件实现
2、基于注解方式实现(使用)
3、在项目工程中引入AOP相关依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
4、切入点表达式
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构
execution(【权限修饰符】【返回类型】【类全路径】【方法名称】【参数列表】)
举例1:对Dao类里面的add进行增强
//*表示所有修饰符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W3AMplum-1661344646786)(D:/工具/typora/images/image-20220706165239666.png)]
举例2:对Dao类中所有方法进行增强
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yvcjKA16-1661344646786)(D:/工具/typora/images/image-20220706165357078.png)]
举例3:对Dao包里面所有类,类中所有方法进行增强
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-90kLIF9Z-1661344646786)(D:/工具/typora/images/image-20220706165535945.png)]
5、AOP操作(AspectJ注解)
1、创建类,在类里面定义方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-INsBIEem-1661344646786)(D:/工具/typora/images/image-20220706171602927.png)]
2、创建增强类(编写增强逻辑)
1)在增强类里面,创建方法,让不同方法代表不同通知类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nkzJtxlh-1661344646787)(D:/工具/typora/images/image-20220706172351916.png)]
3、进行通知的配置
1)在spring配置文件中开启注解扫描
加入context和aop名称空间
<context:component-scan base-package="aop"></context:component-scan>
对目标类开启扫描
2)使用注解创建User和UserProxy
3)在增强类上面添加注解@Aspect
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-stt94gX8-1661344646787)(D:/工具/typora/images/image-20220706183550322.png)]
4)在spring配置文件中开启生成代理对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vS4gLNZL-1661344646787)(D:/工具/typora/images/image-20220706183820718.png)]
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
这句话的意思是找到有@Aspect注解的类,生成代理对象
4、配置不同类型的通知
1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FZ8uMV4s-1661344646787)(D:/工具/typora/images/image-20220706185048048.png)]
例:前置通知
特别要注意的是@Around()
需要在增强类的增强方法中加入ProceedingJoinPoint proceedingJoinPoint
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0OiefHF-1661344646788)(D:/工具/typora/images/image-20220706192951706.png)]
proceedingJoinPoint.proceed()为被增强的方法
5、相同的切入点抽取
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DDP55p9Y-1661344646788)(D:/工具/typora/images/image-20220706194531713.png)]
使用@PointCut注解提取相同的切入点
6、有多个增强类对同一个方法进行增强,设置增强类的优先级
1)在增强类上面添加注解@Order(数字),越小优先级越高
优先级越高越先实现
6、AOP操作(AspectJ配置文件)
1、创建两个类,一个增强类,一个被增强类,创建方法
2、在spring配置文件中创建两个类对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wuSse0j1-1661344646788)(D:/工具/typora/images/image-20220706195839083.png)]
3、在spring配置文件中配置切入点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pPjeYrrJ-1661344646788)(D:/工具/typora/images/image-20220706200203406.png)]
4、完全注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-szK2wmrX-1661344646789)(D:/工具/typora/images/image-20220706201027947.png)]
创建配置类,不需要创建xml配置文件
@Configuration:说明当前类为配置类
@ComponentScan(basepackangs=(类路径)):设置扫描在哪些包下找到bean
@EnableAspectAutoproxy:
这个注解就相当于在传统的xml配置文件中添加 aop:aspectj-autoproxy一样,
自动扫描增强类
这句话的意思是找到有@Aspect注解的类,生成代理对象