javascript
Spring Aop面向切面编程自动注入
1.面向切面編程
在程序原有縱向執(zhí)行流程中,針對(duì)某一個(gè)或某一些方法添加通知,形成橫切面的過(guò)程叫做面向切面編程
2.常用概念
原有功能:切點(diǎn),pointcut
前置通知:在切點(diǎn)之前執(zhí)行的功能,before advice
后置通知:在切點(diǎn)之后執(zhí)行的功能,after advice
如果切點(diǎn)執(zhí)行過(guò)程中出現(xiàn)異常,會(huì)觸發(fā)異常通知,throws advice
所有功能的總稱叫做切面
織入:把切面嵌入原有功能的過(guò)程叫做織入
3.Schema-based方式
每個(gè)通知都需要實(shí)現(xiàn)接口或類(lèi)
配置spring配置文件時(shí)在<aop:config>配置
4.AspectJ方式
每個(gè)通知不需要實(shí)現(xiàn)接口或類(lèi)
配置spring配置文件時(shí)在<aop:config>的子標(biāo)簽<aop:aspect>中配置
5.Schema-based
Demo.java
public class Demo {public void demo1(){System.out.println("demo1");}public void demo2(){System.out.println("demo2");}public void demo3(){System.out.println("demo3");} }(1)導(dǎo)入jar包
aopalliance-1.0.jar
aspectjweaver-1.9.2.jar
(2)新建前置通知類(lèi)
arg0:切點(diǎn)方法對(duì)象Method對(duì)象
arg1:切點(diǎn)方法參數(shù)
arg2:切點(diǎn)方法所在類(lèi)的對(duì)象
public class MyBeforeAdvice implements MethodBeforeAdvice{@Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {System.out.println("執(zhí)行前置通知");} }(3)新建后置通知類(lèi)
arg0:切點(diǎn)方法返回值
arg1:切點(diǎn)方法對(duì)象Method對(duì)象
arg2:切點(diǎn)方法參數(shù)
arg3:切點(diǎn)方法所在類(lèi)的對(duì)象
public class MyAfterAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {System.out.println("執(zhí)行后置通知");} }(4)配置spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 配置通知類(lèi)的對(duì)象,在切面中引入 --> <bean id="mybefore" class="com.mxj.advice.MyBeforeAdvice"></bean> <bean id="myafter" class="com.mxj.advice.MyAfterAdvice"></bean><!-- 配置切面 --><aop:config><!-- 配置切點(diǎn) *通配符:匹配任意方法名,任意類(lèi)名,任意一級(jí)包名;(..):任意類(lèi)型參數(shù)--><aop:pointcut expression="execution(* com.mxj.test.Demo.demo2())" id="mypoint"/><!-- 通知 --><aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/><aop:advisor advice-ref="myafter" pointcut-ref="mypoint"/></aop:config><!-- 配置Demo類(lèi) --><bean id="demo" class="com.mxj.test.Demo"></bean> </beans>?6.配置異常通知的步驟(AspectJ方式)
(1)只有切點(diǎn)報(bào)異常才能觸發(fā)異常通知
(2)在spring中只有AspectJ方式提供了異常通知的方法
(3)實(shí)現(xiàn)步驟
新建類(lèi),在類(lèi)中寫(xiě)任意名稱的方法
public class MyThrowAdvice {public void myexception(){System.out.println("執(zhí)行異常通知");} }在spring配置文件中配置
<aop:aspect>的ref屬性表示:方法在哪個(gè)類(lèi)中
<aop:xxxx/>表示xxx通知
method:當(dāng)觸發(fā)這個(gè)通知時(shí)調(diào)用哪個(gè)方法
throwing:異常對(duì)象名,必須和通知中方法參數(shù)名相同(可以不在通知中聲明異常對(duì)象)
<bean id="mythrow" class="com.mxj.advice.MyThrowAdvice"></bean><aop:config><aop:aspect ref="mythrow"><aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/><aop:after-throwing method="myexception()" pointcut-ref="mypoint" throwing="e"/></aop:aspect></aop:config><bean id="demo" class="com.mxj.test.Demo"></bean>7.異常通知(Schema-based方式)
? (1)新建一個(gè)類(lèi)實(shí)現(xiàn)throwsAdvice接口
public class MyThrow implements ThrowsAdvice{public void afterThrowing(Exception ex) throws Throwable {System.out.println("執(zhí)行異常通知:schema-base方式");} }(2)配置applicationContext.xml
<bean id="mythrow" class="com.mxj.advice.MyThrow"></bean><aop:config><aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/><aop:advisor advice-ref="mythrow" pointcut-ref="mypoint"/></aop:config><bean id="demo" class="com.mxj.test.Demo"></bean>8.環(huán)繞通知(Schema-based方式)
把前置通知和后置通知都寫(xiě)到一個(gè)通知中,就組成了環(huán)繞通知
(1)新建一個(gè)類(lèi)實(shí)現(xiàn) MethodInterceptor(攔截器)
public class MyArround implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation arg0) throws Throwable {System.out.println("環(huán)繞-前置");Object result = arg0.proceed();System.out.println("環(huán)繞-后置");return result;} }(2)配置applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 異常通知 --><!-- <bean id="mythrow" class="com.mxj.advice.MyThrow"></bean><aop:config><aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/><aop:advisor advice-ref="mythrow" pointcut-ref="mypoint"/></aop:config><bean id="demo" class="com.mxj.test.Demo"></bean> --><bean id="myarround" class="com.mxj.advice.MyArround"></bean><aop:config><aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/><aop:advisor advice-ref="myarround" pointcut-ref="mypoint"/></aop:config><bean id="demo" class="com.mxj.test.Demo"></bean> </beans>?9.AspectJ方式實(shí)現(xiàn)
類(lèi)中方法名任意
public class MyAdvice {public void mybefore(){System.out.println("前置");}public void myafter(){System.out.println("后置1");}public void myaftering(){System.out.println("后置2");}public void mythrow(){System.out.println("異常");}public Object myarround(ProceedingJoinPoint p) throws Throwable{System.out.println("執(zhí)行環(huán)繞");System.out.println("環(huán)繞-前置");Object result = p.proceed();System.out.println("環(huán)繞-后置");return result;} }配置spring配置文件
<aop:after/> 后置通知,是否出現(xiàn)異常都執(zhí)行
<aop:after-returning/> 后置通知,只有當(dāng)切點(diǎn)正確執(zhí)行時(shí)執(zhí)行
<aop:after/>、<aop:after-returning/>、<aop:after-throwing/>執(zhí)行順序和配置順序有關(guān)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="demo" class="com.mxj.test.Demo"></bean> <bean id="myadvice" class="com.mxj.advice.MyAdvice"></bean><aop:config><aop:aspect ref="myadvice"><aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/><aop:before method="mybefore" pointcut-ref="mypoint"/><aop:after method="myafter" pointcut-ref="mypoint"/><aop:after-returning method="myaftering" pointcut-ref="mypoint"/><aop:after-throwing method="mythrow" pointcut-ref="mypoint"/><aop:around method="myarround" pointcut-ref="mypoint"/></aop:aspect></aop:config> </beans>?10.AspectJ方式在通知中獲取切點(diǎn)參數(shù)
public class MyAdvice {public void mybefore(String name,int age){System.out.println("前置"+name+" "+age);} }配置文件
<bean id="demo" class="com.mxj.test.Demo"></bean> <bean id="myadvice" class="com.mxj.advice.MyAdvice"></bean><aop:config><aop:aspect ref="myadvice"><aop:pointcut expression="execution(* com.mxj.test.Demo.demo1(String,int)) and args(name,age)" id="mypoint"/><aop:before method="mybefore" pointcut-ref="mypoint" arg-names="name,age"/></aop:aspect></aop:config>?11.使用注解配置AOP(基于Aspect)
spring不會(huì)自動(dòng)尋找注解,必須告訴spring哪些包下類(lèi)可能有注解
(1)引入xmlns:context
(2)@Component
相當(dāng)于<bean/>標(biāo)簽
如果沒(méi)有參數(shù),把類(lèi)名首字母變小寫(xiě),相當(dāng)于<bean id=""/>
@Component("自定義名稱")
(3)實(shí)現(xiàn)步驟
在spring文件中設(shè)置注解在哪些包中
<context:component-scan base-package="com.mxj.advice,com.mxj.test"></context:component-scan> <!--proxy-target-classtrue:使用cglib動(dòng)態(tài)代理false:使用jdk動(dòng)態(tài)代理--><aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
在Demo類(lèi)中添加@Componet
在方法上添加@Pointcut("")定義切點(diǎn)
@Component public class Demo { @Pointcut("execution(* com.mxj.test.Demo.demo1())")public void demo1() throws Exception{System.out.println("demo1");} }在通知類(lèi)中配置
@Component類(lèi)被spring管理
@Aspect 相當(dāng)于<aop:aspect/>表示通知方法在當(dāng)前類(lèi)中
@Component @Aspect public class MyAdvice {@Before("com.mxj.test.Demo.demo1()")public void mybefore(){System.out.println("前置");}@After("com.mxj.test.Demo.demo1()")public void myafter(){System.out.println("后置");}@AfterThrowing("com.mxj.test.Demo.demo1()")public void mythrow(){System.out.println("異常通知");}@Around("com.mxj.test.Demo.demo1()")public Object myarround(ProceedingJoinPoint p) throws Throwable{System.out.println("環(huán)繞-前置");Object result = p.proceed();System.out.println("環(huán)繞-后置");return result;} }?12.自動(dòng)注入
在Spring配置文件中對(duì)象名和ref="id" id名相同使用自動(dòng)注入,可以不配置<property/>
兩種配置方法:
(1)在<bean>中通過(guò)autowire=""配置,只對(duì)<bean>生效
(2)在<beans>中通過(guò)default-autowire=""配置,表示當(dāng)前文件中所有的<bean>都走全局配置
(3)autowire=""可取值
default:默認(rèn)值,根據(jù)全局default-autowire=""值,默認(rèn)全局和局部都沒(méi)有配置情況下,相當(dāng)于no
no:不自動(dòng)注入
byName:通過(guò)名稱自動(dòng)注入,在Spring容器中找類(lèi)的id
byType:根據(jù)類(lèi)型注入
spring容器中不可以出現(xiàn)兩個(gè)相同類(lèi)型的<bean>
constructor:根據(jù)構(gòu)造方法注入
提供對(duì)應(yīng)參數(shù)的構(gòu)造方法(構(gòu)造方法參數(shù)中包含注入對(duì)象)
底層使用byName,構(gòu)造方法參數(shù)名和其他<bean>的id相同
13.Spring中加載properties文件
(1)在src下新建xxx.properties文件
(2)在spring配置文件中先引入xmlns:context
如果需要記載多個(gè)文件逗號(hào)分割
<context:property-placeholder location="classpath:db.properties"/>(3)添加屬性文件加載,在<beans>中開(kāi)啟自動(dòng)注入需要注意的地方:
SqlSessionFactoryBean的id不能叫做sqlSessionFactory
修改:把原來(lái)通過(guò)ref引用替換成value賦值,自動(dòng)注入只能影響ref,不會(huì)影響value賦值
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.mxj.mapper"></property><property name="sqlSessionFactoryBeanName" value="factory"></property> </bean>?14.Spring加載屬性文件
在被Spring管理的類(lèi)中通過(guò)@Value("{key}")取出properties中內(nèi)容
(1)添加注解掃描
<context:component-scan base-package="com.mxj.service.impl"></context:component-scan>(2)在類(lèi)中添加
key和變量名可以不相同
變量類(lèi)型任意,只要保證key對(duì)應(yīng)的value能轉(zhuǎn)換成這個(gè)類(lèi)型就可以
@Value("${my.demo}") private String test;?15.scope屬性
(1)<bean>的屬性
(2)作用:控制對(duì)象有效范圍(單例,多例等)
(3)<bean/>標(biāo)簽對(duì)應(yīng)的對(duì)象默認(rèn)是單例的,無(wú)論獲取多少次都是一個(gè)對(duì)象
(4)scope可取值
singleton:默認(rèn)值,單例
prototype: 多例,每次獲取重新實(shí)例化
request: 每次請(qǐng)求重新實(shí)例化
session:每個(gè)會(huì)話對(duì)象內(nèi),對(duì)象是單例的
application:在application對(duì)象內(nèi)是單例
global session spring推出一個(gè)對(duì)象,依賴于spring-webmvc-portlet,類(lèi)似于session
轉(zhuǎn)載于:https://www.cnblogs.com/mxj961116/p/11265517.html
總結(jié)
以上是生活随笔為你收集整理的Spring Aop面向切面编程自动注入的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Unity 编译apk启动出异常
- 下一篇: 实训笔记(一) 创建文件夹(SDCard