为神马要引入aop编程范式
aop的好处及适用场景是哪些
aop的两大核心
AOP 的核心思想: 将应用程序中的商业逻辑和对其提供支持的通用服务进行分离。
尽管面向对象编程与面向过程相比减少了代码的重复,但是它仍然留下了大量的重复代码。面向对象设计有助于最小化应用程序逻辑的代码重复,但是对于实现横切关注点的代码仍然很难实现模块化,例如日志,虽然我们可以使用类似于log4Net这样的类库来灵活的记录日志, 但是记录日志的代码却遍布于程序之中,其中有大量的重复。
使用AOP却可以很好的解决这方面的问题。
- 核心代码中不在包含记录日志的代码, 类更专注于它的职责。
- 如果想修改日志的记录方式, 不需要修改Account类,只需要修改相应的配置文件和日志的实现,修改工作量小。
- 使用这种方式可以动态的修改业务规则而不用修改Account类, 也不用重新编译发布。例如Account.WithDraw()方法的核心是减少账户余额,假设程序布署后客户又来一新的需求,当账户余额小于50元时,发邮件通知客户,此时只需要像添加日志一样实现这一功能,配置到程序上去就好了。最适合移入方面的业务规则是那些在实现核心逻辑的同时也需要实现的二级逻辑的规则。
- 实现AOP的同时需要依赖注入, 这又会减少模块间的依赖。
- 依赖注入要用到Ioc容器, 这个又可以代替工厂类,这算是又一个好处吧
- 第一种实例:
- <!-- 静态增强方法 -->
- <bean id="greetingBefore" class="dream.advice.GreetingBeforeAdvice"></bean>
- <!-- 静态匹配切面-->
- <bean id="greetingAdvistor" class="dream.advice.GreetingAdvisor">
- <!--需要在切面中注入增强方法-->
- <property name="advice" ref="greetingBefore"></property>
- </bean>
- <!-- 静态匹配目标 -->
- <bean id="waiterStatic" class="dream.biz.imple.Waiter"></bean>
- <bean id="seller" class="dream.biz.imple.Seller"></bean>
- <!-- 静态普通匹配切面代理 -->
- <bean id="parent" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="interceptorNames">
- <list>
- <value>greetingAdvistor</value>
- </list>
- </property>
- <property name="proxyTargetClass" value="true"></property>
- </bean>
- <!-- waiter代理 -->
- <bean id="waiter1" parent="parent">
- <property name="target" ref="waiterStatic"></property>
- </bean>
- <!-- seller代理 -->
- <bean id="seller1" parent="parent">
- <property name="target" ref="seller"></property>
- </bean>
- 第二种实例:无需使用顾问
- <!--增强方法 -->
- <bean id="greetingBefore" class="dream.advice.GreetingBeforeAdvice"></bean>
- <!-- 静态匹配目标 -->
- <bean id="waiterStatic" class="dream.biz.imple.Waiter"></bean>
- <bean id="seller" class="dream.biz.imple.Seller"></bean>
- <!-- 静态正则表达式方法匹配切面 -->
- <bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
- <property name="patterns">
- <list>
- <value>.*greetTo.*</value>
- </list>
- </property>
- <property name="advice" ref="greetingBefore"></property>
- </bean>
- <bean id="Reg" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean">
- <!-- 拦截 -->
- <property name="interceptorNames">
- <list>
- <value>regexpAdvisor</value>
- </list>
- </property>
- <property name="proxyTargetClass" value="true"></property>
- </bean>
- <bean id="waiterReg" parent="Reg">
- <property name="target" ref="waiterStatic"></property>
- </bean>
- <bean id="SellerReg" parent="Reg">
- <property name="target" ref="seller"></property>
- </bean>