Spring之AspectJ面向切面编程框架以及SSH整合详解

本文介绍Spring AOP及AspectJ的原理与应用,详细解释通知、切点与织入的概念,并通过XML配置和注解两种方式演示如何在实际项目中实施面向切面编程。

Spring AspectJ

AspectJ是什么?

面向切面编程框架
它扩展了Java语言(它也是一种语言) 支持原生Java代码
它有自己的编译器 将代码翻译成标准的Java字节码
为了方便编写AOP代码而出现的

使用AOP思路
    三个重点 通知 切点 织入

xml配置完成AOP

实现步骤

1.创建通知类 添加需要的方法(前置 后置 环绕 后置returning throwing)
2.在配置文件中添加通知类的bean
3.添加<aop:config> 添加子标签pointCut

代码实现

通知:
    public class MyAdvice {

        // 前置通知
        public void before() {
            System.out.println("前置");
        }
        // 后置通知 始终会执行
        public void after() {
            System.out.println("后置");
        }
        // 环绕通知
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("环绕增强前");
            Object result = pjp.proceed();
            System.out.println("环绕增强后");
            System.out.println(1/0);
            return result;
        }
        // 后置 发生异常时 不会执行
        public void returning() {
            System.out.println("After returning");
        }
        // 发生异常
        public void throwing() {
            System.out.println("发生异常");
        }
    }

applicationContext.xml:
    <!-- 准备通知对象 -->
    <bean name="adc" class="com.lanou.advice.MyAdvice"></bean>

    <!-- 创建切入点 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.lanou.dao.impl.*.*(..))" id="point"/>
        <aop:aspect ref="adc">
            <!-- 按照顺序写方法 前 环绕 后 -->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:around method="around" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
            <aop:after-returning method="returning" pointcut-ref="point"/>
            <aop:after-throwing method="throwing" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>


    <!-- 开启扫描注解 -->
    <context:component-scan base-package="com.lanou"></context:component-scan>

测试:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class MyTest {

        // 注入UserDao
        @Autowired
        private UserDao userDao;

        @Autowired
        private User user;

        @Test
        public void test() {
            userDao.addUser(user);
        }
    }

注解配置完成AOP

实现步骤

1.创建通知类
2.添加@Aspect设置通知类
3.创建切点方法
4.给通知方法加上相应的注解
    after before等....

代码实现

通知:
    //将这个类作为通知类的注解
    @Aspect  
    @Component
    public class MyAdvice_annotion {
        // 定义切入点
        @Pointcut("execution(* com.lanou.dao.impl.*.*(..))")
        public void point() {}


        // 前置通知
        @Before("point()")
        public void before() {
            System.out.println("前置");
        }
        // 后置通知 始终会执行
        @After("point()")
        public void after() {
            System.out.println("后置");
        }
        // 环绕通知
        @Around("point()")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("环绕增强前");
            Object result = pjp.proceed();
            System.out.println("环绕增强后");
            System.out.println(1/0);
            return result;
    //      throw new RuntimeException("异常");
        }
        // 后置 发生异常时 不会执行
        @AfterReturning("point()")
        public void returning() {
            System.out.println("After returning");
        }
        // 发生异常
        @AfterThrowing("point()")
        public void throwing() {
            System.out.println("发生异常");
        }
    }

applicationContext1.xml:
    <!-- 测试AOP注解 不需要任何属性 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>


    <!-- 开启扫描注解 -->
    <context:component-scan base-package="com.lanou"></context:component-scan>

测试:
    <!--同上 修改-->
    @ContextConfiguration("classpath:applicationContext1.xml")

SSH整合

第一步:导jar包
第二步:单独配置Spring Struts 
第三步:整合Spring和Struts
    配置文件没有任何区别仅仅将Action中class的值从原来的类名换成Spring中bean的名称
    注意:Spring默认是单例 如果Action放在Spring中 则需要修改Scope为prototype
第四步:单独配置Hibernate
第五步:整合Hibernate
    将SessionFactory交给Spring管理
    注意:
    <property name="mappingDirectoryLocations" value="com/lanou/bean"></property>
    绑定线程在整合不要写

配置Spring

<!-- 使用监听器启动Spring容器 -->
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>

配置Struts2

<struts>
    <package name="user" namespace="/" extends="struts-default">
        <action name="UserAction_*" class="com.lanou.action.UserAction" method="{1}">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>
<!-- Struts2核心过滤器 -->
<filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

整合Spring和Struts2

struts.xml

<struts>
    <!-- <constant name="struts.objectFactory" value="spring"></constant> -->
    <!-- 
        让Spring来管理Action的生命周期 和依赖关系
        处于半整合状态 目前Action还是由struts创建的
        **作为了解
        这个常量不是用来控制是否启动Spring 它的默认值就是Spring  
    -->
    <!-- 
        struts.objectFactory.spring.autoWire = name 该参数不用修改
        让Spring对Action中的依赖进行注入 通过name来注入
    -->

    <!-- 第一种整合方式
        Struts配置文件不需要做任何修改 这样的话 Action的创建还是由Struts完成
        Spring只负责依赖管理  不推荐


        第二种完全整合
        把Struts配置中的Action的class替换为Spring容器中的bean的名称
        达到 让Spring完全管理所有Action和依赖
    -->
    <package name="user" namespace="/" extends="struts-default">
        <action name="UserAction_*" class="userAction" method="{1}">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>

applicationContext.xml

<!-- 这是struts中的某个Action 可以用注解来减少配置文件 -->
<bean name="userAction" class="com.lanou.action.UserAction" scope="prototype"></bean>

配置Hibernate

常规配置hibernate.cfg.xml

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///MyDB</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">123456</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>


        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- SSH整合时这个属性千万不要加 因为session的生命周期已经交给了Spring -->
        <property name="hibernate.current_session_context_class">thread</property>

        <mapping resource="com/lanou/bean/User.hbm.xml" />

    </session-factory>
</hibernate-configuration>

整合Hibernate

applicationContext.xml

<!-- 整合Hibernate其实就是让Spring接管SessionFactory -->
<bean name="sessionFactory"
    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <!-- 该属性用来设置JDBC相关参数 -->
    <property name="hibernateProperties">
        <props>
            <!-- 必选 -->
            <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
            <prop key="hibernate.connection.url">jdbc:mysql:///MyDB</prop>
            <prop key="hibernate.connection.username">root</prop>
            <prop key="hibernate.connection.password">123456</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
            <!-- 可选 -->
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
    <!-- 指定映射文件的路径 -->
    <property name="mappingDirectoryLocations" value="com/lanou/bean"></property>
</bean>


<!-- 打开扫描注解 -->
<context:component-scan base-package="com.lanou.serviceImpl"></context:component-scan>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值