javascript
Spring Aop面向切面编程自动注入
1.面向切面編程
在程序原有縱向執(zhí)行流程中,針對某一個或某一些方法添加通知,形成橫切面的過程叫做面向切面編程
2.常用概念
原有功能:切點,pointcut
前置通知:在切點之前執(zhí)行的功能,before advice
后置通知:在切點之后執(zhí)行的功能,after advice
如果切點執(zhí)行過程中出現(xiàn)異常,會觸發(fā)異常通知,throws advice
所有功能的總稱叫做切面
織入:把切面嵌入原有功能的過程叫做織入
3.Schema-based方式
每個通知都需要實現(xiàn)接口或類
配置spring配置文件時在<aop:config>配置
4.AspectJ方式
每個通知不需要實現(xiàn)接口或類
配置spring配置文件時在<aop:config>的子標簽<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)導入jar包
aopalliance-1.0.jar
aspectjweaver-1.9.2.jar
(2)新建前置通知類
arg0:切點方法對象Method對象
arg1:切點方法參數(shù)
arg2:切點方法所在類的對象
public class MyBeforeAdvice implements MethodBeforeAdvice{@Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {System.out.println("執(zhí)行前置通知");} }(3)新建后置通知類
arg0:切點方法返回值
arg1:切點方法對象Method對象
arg2:切點方法參數(shù)
arg3:切點方法所在類的對象
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"><!-- 配置通知類的對象,在切面中引入 --> <bean id="mybefore" class="com.mxj.advice.MyBeforeAdvice"></bean> <bean id="myafter" class="com.mxj.advice.MyAfterAdvice"></bean><!-- 配置切面 --><aop:config><!-- 配置切點 *通配符:匹配任意方法名,任意類名,任意一級包名;(..):任意類型參數(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類 --><bean id="demo" class="com.mxj.test.Demo"></bean> </beans>?6.配置異常通知的步驟(AspectJ方式)
(1)只有切點報異常才能觸發(fā)異常通知
(2)在spring中只有AspectJ方式提供了異常通知的方法
(3)實現(xiàn)步驟
新建類,在類中寫任意名稱的方法
public class MyThrowAdvice {public void myexception(){System.out.println("執(zhí)行異常通知");} }在spring配置文件中配置
<aop:aspect>的ref屬性表示:方法在哪個類中
<aop:xxxx/>表示xxx通知
method:當觸發(fā)這個通知時調用哪個方法
throwing:異常對象名,必須和通知中方法參數(shù)名相同(可以不在通知中聲明異常對象)
<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)新建一個類實現(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方式)
把前置通知和后置通知都寫到一個通知中,就組成了環(huán)繞通知
(1)新建一個類實現(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方式實現(xiàn)
類中方法名任意
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/> 后置通知,只有當切點正確執(zhí)行時執(zhí)行
<aop:after/>、<aop:after-returning/>、<aop:after-throwing/>執(zhí)行順序和配置順序有關
<?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方式在通知中獲取切點參數(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不會自動尋找注解,必須告訴spring哪些包下類可能有注解
(1)引入xmlns:context
(2)@Component
相當于<bean/>標簽
如果沒有參數(shù),把類名首字母變小寫,相當于<bean id=""/>
@Component("自定義名稱")
(3)實現(xiàn)步驟
在spring文件中設置注解在哪些包中
<context:component-scan base-package="com.mxj.advice,com.mxj.test"></context:component-scan> <!--proxy-target-classtrue:使用cglib動態(tài)代理false:使用jdk動態(tài)代理--><aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
在Demo類中添加@Componet
在方法上添加@Pointcut("")定義切點
@Component public class Demo { @Pointcut("execution(* com.mxj.test.Demo.demo1())")public void demo1() throws Exception{System.out.println("demo1");} }在通知類中配置
@Component類被spring管理
@Aspect 相當于<aop:aspect/>表示通知方法在當前類中
@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.自動注入
在Spring配置文件中對象名和ref="id" id名相同使用自動注入,可以不配置<property/>
兩種配置方法:
(1)在<bean>中通過autowire=""配置,只對<bean>生效
(2)在<beans>中通過default-autowire=""配置,表示當前文件中所有的<bean>都走全局配置
(3)autowire=""可取值
default:默認值,根據(jù)全局default-autowire=""值,默認全局和局部都沒有配置情況下,相當于no
no:不自動注入
byName:通過名稱自動注入,在Spring容器中找類的id
byType:根據(jù)類型注入
spring容器中不可以出現(xiàn)兩個相同類型的<bean>
constructor:根據(jù)構造方法注入
提供對應參數(shù)的構造方法(構造方法參數(shù)中包含注入對象)
底層使用byName,構造方法參數(shù)名和其他<bean>的id相同
13.Spring中加載properties文件
(1)在src下新建xxx.properties文件
(2)在spring配置文件中先引入xmlns:context
如果需要記載多個文件逗號分割
<context:property-placeholder location="classpath:db.properties"/>(3)添加屬性文件加載,在<beans>中開啟自動注入需要注意的地方:
SqlSessionFactoryBean的id不能叫做sqlSessionFactory
修改:把原來通過ref引用替換成value賦值,自動注入只能影響ref,不會影響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管理的類中通過@Value("{key}")取出properties中內容
(1)添加注解掃描
<context:component-scan base-package="com.mxj.service.impl"></context:component-scan>(2)在類中添加
key和變量名可以不相同
變量類型任意,只要保證key對應的value能轉換成這個類型就可以
@Value("${my.demo}") private String test;?15.scope屬性
(1)<bean>的屬性
(2)作用:控制對象有效范圍(單例,多例等)
(3)<bean/>標簽對應的對象默認是單例的,無論獲取多少次都是一個對象
(4)scope可取值
singleton:默認值,單例
prototype: 多例,每次獲取重新實例化
request: 每次請求重新實例化
session:每個會話對象內,對象是單例的
application:在application對象內是單例
global session spring推出一個對象,依賴于spring-webmvc-portlet,類似于session
轉載于:https://www.cnblogs.com/mxj961116/p/11265517.html
總結
以上是生活随笔為你收集整理的Spring Aop面向切面编程自动注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity 编译apk启动出异常
- 下一篇: JavaScript代码(一)