课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > 【昆明Java培训班】什么是AOP?
  • 【昆明Java培训班】什么是AOP?

    发布:昆明Java培训      来源:达内新闻      时间:2016-10-21

  • 昆明Java培训班的老师今天给大家讲什么是AOP。

    面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面

    1.面向切面编程提供声明式事务管理

    2.spring支持用户自定义的切面

    面向切面编程(aop)是对面向对象编程(oop)的补充,

    面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。

    AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,

    是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。

    aop框架具有的两个特征:

    1.各个步骤之间的良好隔离性

    2.源代码无关性

    话不多说,我们直接来代码,加强理解

    昆明Java培训班的老师先给大家看一个简单的例子:Spring AOP实现日志的输出,即后置增强和前置增强

    我们看看代码

    aop包下

    我们要实现AfterReturningAdvice接口

    public class LoggerAfter implements AfterReturningAdvice {

    //save()之后执行它

    public void afterReturning(Object returnValue, Method method, Object[] arguments   ,

    Object target) throws Throwable {

    System.out.println("===========后置增强代码==========");

    }

    }

    前置,我们要实现MethodBeforeAdvice接口

    */

    public class LoggerBefore implements MethodBeforeAdvice {

    //获取日志对象

    private static final Logger log = Logger.getLogger(LoggerBefore.class);

    //save()之前执行它

    public void before(Method method, Object[] arguments, Object target)

    throws Throwable {

    log.info("==========前置增强代码==========");

    }

    }

    实现类:

    biz:

    public class UserBiz implements IUserBiz {

    //实例化所依赖的UserDao对象,植入接口对象

    private IDao dao;

    public void save2(User user) {       

    //调用UserDao的方法保存信息

    dao.save(user);

    }

    //dao属性的setter访问器,会被Spring调用,实现设值注入

    public IDao getDao() {

    return dao;

    }

    public void setDao(IDao dao) {

    this.dao = dao;

    }

    dao:

    public class UserDao implements IDao {

    /**

    *保存用户信息的方法

    * @param user

    */

    public void save(User user) {

    System.out.println("save success!");

    }

    }

    src下的applicationContext.xml

    <!--配置实现类 -->

    <bean id="dao" class="cn.wgy.day01.dao.impl.UserDao"/>

    <bean id="biz" class="cn.wgy.day01.biz.impl.UserBiz">

    <property name="dao" ref="dao"></property>

    </bean>

    <!--定义前置增强组件-->

    <bean id="loggerBefore" class="cn.wgy.day01.aop.LoggerBefore"/>

    <!--定义后置增强组件-->

    <bean id="loggerAfter" class="cn.wgy.day01.aop.LoggerAfter"/>

    <!--代理对象ProxyFactoryBean代理工厂bean-->

    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="targetName" value="biz"></property>

    <property ame="interceptorNames" value="loggerBefore,loggerAfter"></property>

    </bean>

    <!--针对AOP的配置

    <aop:config>

    execution:调用那个方法

    <aop:pointcut id="pointcut" expression="execution(public void save2(cn.wgy.day01.entity.User))"/>

    将增强处理和切入点结合在一起,在切入点处插入增强处理,完成"织入"

    <aop:advisor pointcut-ref="pointcut" advice-ref="loggerBefore"/>

    <aop:advisor pointcut-ref="pointcut" advice-ref="loggerAfter"/>

    </aop:config> -->

    test

    public static void main(String[] args) {

    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

    //获取到biz对象,即业务逻辑层对象

    IUserBiz biz=(IUserBiz)ctx.getBean("serviceProxy");

    User user=new User();

    /**

    *执行这个方法时,先走前置增强,before(),然后走中间的方法,最后走后置增强

    */

    biz.save2(user);

    System.out.println("success!");

    }

    这个简单的例子就很好的体现出了Spring AOP的力量

    顺便我们一起来看看其他增强类型

    环绕增强:可以把前置增强和后置增强结合起来,spring吧目标的方法的控制权全部交给了它。我们要实现MethodInterceptor接口

    aop:

    public class AroundLog implements MethodInterceptor {

    private static final Logger log = Logger.getLogger(AroundLog.class);

    public Object invoke(MethodInvocation arg0) throws Throwable {

    /*Object target = arg0.getThis(); //获取被代理对象

    Method method = arg0.getMethod(); //获取被代理方法

    Object[] args = arg0.getArguments(); //获取方法参数

    log.info("调用" + target + "的" + method.getName() + "方法。方法入参:"

    + Arrays.toString(args));

    try {   Object result = arg0.proceed(); //调用目标方法,获取目标方法返回值

    log.info("调用" + target + "的" + method.getName() + "方法。"

    + "方法返回值:" + result);

    return result;

    } catch (Throwable e) {

    log.error(method.getName() + "方法发生异常:" + e);       throw e;

    }*/

    //环绕增强

    System.out.println("===before=====");

    //调用目标对象的方法

    Object result = arg0.proceed();

    System.out.println("===after=====");

    return result;

    }

    applicationContext.xml:

    <bean id="service" class="cn.wgy.day01.service.UserService"/>

    <!--环绕增强 -->

    <bean id="around" class="cn.wgy.day01.aop.AroundLog"/>

    <!--方式一-->

    <!-- <aop:config>

    切点

    <aop:pointcut expression="execution(public void delete())" id="pointcut"/>

    异常抛出增强

    <aop:advisor advice-ref="around" pointcut-ref="pointcut"/>

    </aop:config> -->

    <!--方式二 -->

    <!--代理对象ProxyFactoryBean代理工厂bean-->

    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="service"></property>

    <property ame="interceptorNames" value="around"></property>

    </bean>

    </beans>

    异常增强,我们要实现ThrowsAdvice接口

    你注意看没有,都没有实现方法,怎么办呢?你别急,其实已经给我们规定了方法名称,而且必须是它才能。就是void AfterThrowing()它提供了一个参数,三个参数的。

    aop:

    public class ErrorLog implements ThrowsAdvice {

    private static final Logger log=Logger.getLogger(ErrorLog.class);

    @SuppressWarnings("unused")

    private void AfterThrowing(Method method, Object[] args, Object target,

    RuntimeException e) {

    log.error(method.getName()+"方法发生异常"+e);

    }

    service

    public class UserService {

    public void delete() {

    int result=5/0;

    System.out.println(result);

    }

    }

    applicationContext.xml

    <bean id="service" class="cn.wgy.day01.service.UserService"/>

    <bean id="error" class="cn.wgy.day01.aop.ErrorLog"/>

    <!--方式二 -->

    <!--代理对象ProxyFactoryBean代理工厂bean-->

    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="service"></property>

    <property ame="interceptorNames" value="error"></property>

    </bean>

    <!-- <aop:config>

    <aop:pointcut expression="execution(public void delete())" id="pointcut"/>

    异常抛出增强

    <aop:advisor advice-ref="error" pointcut-ref="pointcut"/>

    </aop:config> -->

    到这里昆明Java培训班的老师要思考一下,我们可以applicationContext.xml里面的bean组件修改修改,我们用了顾问(Advisor)要包装通知(Advice),比较灵活,可以只针对某一个方法进行处理。

    对于环绕增强:

    <bean id="service" class="cn.wgy.day01.service.UserService"/>

    <!--环绕增强 -->

    <bean id="around" class="cn.wgy.day01.aop.AroundLog"/>

    <!--方式一-->

    <!-- <aop:config>

    切点

    <aop:pointcut expression="execution(public void delete())" id="pointcut"/>

    异常抛出增强

    <aop:advisor advice-ref="around" pointcut-ref="pointcut"/>

    </aop:config> -->

    <!--顾问(Advisor)要包装通知(Advice),比较灵活,可以只针对某一个方法进行处理 -->

    <bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

    <property ame="advice" ref="around"></property>

    <property ame="mappedNames" value="delete"></property>

    </bean>

    <!--方式二 -->

    <!--代理对象ProxyFactoryBean代理工厂bean-->

    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="service"></property>

    <property ame="interceptorNames" value="advisor"></property>

    </bean>

    </beans>

    还有一个知识点,我们可以更方便的写bean组件,正则表达式

    <bean id="service" class="cn.wgy.day01.service.UserService"/>

    <!--环绕增强 -->

    <bean id="around" class="cn.wgy.day01.aop.AroundLog"/>

    <!--方式一-->

    <!-- <aop:config>

    切点

    <aop:pointcut expression="execution(public void delete())" id="pointcut"/>

    异常抛出增强

    <aop:advisor advice-ref="around" pointcut-ref="pointcut"/>

    </aop:config> -->

    <bean id="regex" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

    <property ame="advice" ref="around"></property>

    <property ame="pattern" value=".*do.*"></property>

    </bean>

    <!--方式二 -->

    <!--代理对象ProxyFactoryBean代理工厂bean-->

    <!-- <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="service"></property>

    <property ame="interceptorNames" value="regex"></property>

    </bean> -->

    <!--默认-->

    <!-- <bean class="org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor"></bean>-->

    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

    <property name="beanNames" value="service"></property>

    <property name="interceptorNames" value="regex"></property>

    </bean>

    到这里呢,算是差不多了,但是我们缺少了分析下源代码

    昆明Java培训班的老师知道,实现aop,其实源代码里面通过了动态代理来实现

    推荐文章

上一篇:Spring设置注入和构造注入的区别

下一篇:java程序员:代理模式的定义

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:12/29

Java--零基础业余班

Java--零基础业余班

开班日期:12/29

Java--周末提升班

Java--周末提升班

开班日期:12/29

Java--零基础周末班

Java--零基础周末班

开班日期:12/29

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56