zoukankan      html  css  js  c++  java
  • Spring学习_day02_AOP,AspectJ,JdbcTemplate

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用.

    转载请注明 出自 : luogg的博客园 谢谢配合!

    Spring_day02

    一.AOP面向切面编程

    1.1 什么是AOP

    AOP就是面向切面编程,通过预编译的方式和运行期动态代理实现程序功能的统一维护的技术.

    主要的功能是 : 日志记录,性能统计,安全控制,事务处理,异常处理等.

    1.2 AOP实现方式

    一. 预编译

    • AspectJ

    二.运行期动态代理

    • JDK动态代理
    • CGLIB动态代理

    1.3 Spring中的切面类型

    • 1.Advisor : spring中传统切面,
      Advisor : 都是一个切点和一个通知组成
      Aspect : 多个切点和多个通知组成

    Advisor : 代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)

    PointcutAdvisor : 代表具有切点的切面,可以指定拦截目标类哪些方法(带有切点的切面,针对某个方法进行拦截)

    1.4 Spring中AOP开发(针对所有方法增强)

    • 1.导入相应的jar包
      spring-aop-3.2.0.RELEASE.jar AOP联盟的jar包
      com.springsource.org.aopalliance-1.0.0.jar 依赖包

    • 2.编写被代理的对象:
      CustomerDao 接口
      CustomerDaoImpl 实现类

    • 3.编写增强的代码

    public class MyBeforeAdvice implements MethodBeforeAdvice{
    
    	@Override
    	/**
    	 * method:执行的方法
    	 * args:方法的参数
    	 * target:目标对象
    	 */
    	public void before(Method method, Object[] args, Object target) throws Throwable {
    		System.out.println("前置增强");
    	}
    }
    
    • 4.生成代理(通过配置生成代理)

    1.5 Spring的AspectJ的AOP

    AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。

    AspectJ是一个基于Java语言的AOP框架

    Spring2.0以后新增了对AspectJ切点表达式支持

    @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面

    新版本Spring框架,建议使用AspectJ方式来开发AOP

    AspectJ表达式:

    • 语法:execution(表达式)
      execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

    • execution(“* cn.itcast.spring3.demo1.dao.*(..)”) ---只检索当前包

    • execution(“* cn.itcast.spring3.demo1.dao..*(..)”) ---检索包及当前包的子包.

    • execution(* cn.itcast.dao.GenericDAO+.*(..)) ---检索GenericDAO及子类

    AspectJ增强(注解):

    • @Before 前置通知,相当于BeforeAdvice,没有办法阻止目标方法的执行
        /**
    	 * 前置增强
    	 */
    	@Before("execution(* com.luogg.demo1.UserDao.add(..))")
    	public void before(){
    		System.out.println("前置增强===>");
    	}
    
    • @AfterReturning 后置通知,相当于AfterReturningAdvice,可以获得方法的返回值
        /*
    	 * 后置增强
    	 */
    	@AfterReturning(returning="returnVal",value="execution(* com.luogg.demo1.UserDao.delete(..))")
    	public void after(Object returnVal){
    		System.out.println("后置增强===>方法的返回值为:" + returnVal);
    	}
    
    • @Around 环绕通知,相当于MethodInterceptor,而且可以阻止目标方法的执行,在前边加个if判断即可.
        /*
    	 * 环绕增强
    	 */
    	@Around(value="execution(* com.luogg.demo1.UserDao.find(..))")
    	public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
    		System.out.println("环绕前增强");
    		proceedingJoinPoint.proceed();
    		System.out.println("环绕后增强");
    	}
    
    • @AfterThrowing抛出通知,相当于ThrowAdvice
        /**
    	 * 抛出异常
    	 */
    	@AfterThrowing(value="execution(* com.luogg.demo1.UserDao.find(..))",throwing="e")
    	public void err(Throwable e){
    		System.out.println("出异常了"+e.getMessage());
    	}
    
    • @After 最终final通知,不管是否异常,该通知都会执行
        /*
    	 * 最终通知
    	 */
    	@After("execution(* com.luogg.demo1.UserDao.find(..))")
    	public void after(){
    		System.out.println("最终通知");
    	}
    
    • @DeclareParents 引介通知,相当于IntroductionInterceptor (不要求掌握)

    基于注解

    • 第一步 : 引入jar包.
      aspectj依赖aop环境.
      spring-aspects-3.2.0.RELEASE.jar
      com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

    • 第二步 : 编写被代理对象UserDao

    /**
     * 编写被代理对象 用户dao层
     * @author luogg
     *
     */
    
    @Repository("userDao")
    public class UserDao {
    	public void add(){
    		System.out.println("添加用户");
    	}
    	public void delete(){
    		System.out.println("删除用户");
    	}
    	public void update(){
    		System.out.println("修改用户");
    	}
    	public void find(){
    		System.out.println("查询用户");
    	}
    }
    
    • 第三步 : 使用AspectJ注解形式 定义切面,并定义前置增强
    /**
     * 定义一个切面,就是切点和增强的结合
     * @author luogg
     *
     */
    @Service("myAspect")
    @Aspect		//定义切面
    public class MyAspect {
    	
    	/**
    	 * 前置增强
    	 */
    	@Before("execution(* com.luogg.demo1.UserDao.*(..))")
    	public void before(){
    		System.out.println("前置增强");
    	}
    }
    
    • 第四步 : 配置applicationContext.xml配置文件,开启自动生成代理,并扫描bean
        <!-- 开启自动生成代理 -->
    	<aop:aspectj-autoproxy/>
    
    	<!-- 去扫描注解装配的Bean -->
    	<context:component-scan base-package="com.luogg.demo1"></context:component-scan>
    
    • 第五步 : 编写测试类
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class SpringTest1 {
    	@Autowired
    	//@Qualifier("userDao")
    	private UserDao userDao;
    	
    	@Test
    	public void test1(){
    		userDao.add();
    		userDao.delete();
    		userDao.update();
    		userDao.find();
    	}
    }
    

    输出结果

    添加用户
    前置增强
    删除用户
    前置增强
    修改用户
    前置增强
    查询用户

    切点的定义

    在注解中写切点太麻烦了,直接同意定义,然后通过类名.方法名调用同意的切点.

    @Pointcut("execution(* com.luogg.demo1.UserDao.find(..))")
    	public void myPointCut(){}
    	
        /*
    	 * 最终通知
    	 */
    	@After("MyAspect.myPointCut()")
    	public void after(){
    		System.out.println("最终通知");
    	}
    	
    

    面试:

    • Advisor和Aspect的区别?
    • Advisor:Spring传统意义上的切面:支持一个切点和一个通知的组合.
    • Aspect:可以支持多个切点和多个通知的组合.

    1.6 Spring的JdbcTemplate

    Spring对持久层技术的支持

    JDBC : org.springframework.jdbc.core.JdbcTemplate

    Hibernate3.0 : org.springframework.orm.hibernate3.HibernateTemplate

    IBatis(MyBatis) : org.springframework.orm.ibatis.SqlMapClientTemplate

    JPA : org.springframework.orm.jpa.JpaTemplate

    二.Spring的JDBC模板

    2.1 DBCP连接池

    导入jar包:
    * com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
    * com.springsource.org.apache.commons.pool-1.5.3.jar
    
    	<!-- 配置DBCP连接池 -->
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    		<property name="url" value="jdbc:mysql:///spring3_day02"/>
    		<property name="username" value="root"/>
    		<property name="password" value="123"/>
    	</bean>
    

    2.2 C3P0连接池

    导入jar包:
    * com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
    	<!-- 配置c3p0连接池 -->
    	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    		<property name="driverClass" value="com.mysql.jdbc.Driver"/>
    		<property name="jdbcUrl" value="jdbc:mysql:///spring3_day02"/>
    		<property name="user" value="root"/>
    		<property name="password" value="123"/>
        </bean>
    

    2.3 将参数设置到属性文件jdbc.properties中

    在src下创建jdbc.properties
    jdbc.driver = com.mysql.jdbc.Driver
    jdbc.url = jdbc:mysql:///spring3_day02
    jdbc.user = root
    jdbc.password = 123

    需要在applicationContext.xml 中使用属性文件配置的内容.
    * 第一种写法:
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
              <property name="location" value="classpath:jdbc.properties"></property>
    </bean>
    
    * 第二种写法:
    <context:property-placeholder location="classpath:jdbc.properties"/>
    

    2.4 jdbcTemplate 的 CRUD 操作

  • 相关阅读:
    在插入一条记录后 取得自动增长ID
    hashtable,dictionary 从原理上说说有什么异同,哪个性能高一些
    单例模式
    聚簇索引与非聚簇索引的区别
    基于SQL SERVER2008的SCCM2007部署
    XML架构下的表结构设置主键
    IE6与IE7下一点样式的区别
    Session丢失原因与解决方案小结
    Python_如何去除字符串里的空格
    Python_让人脑阔疼的编码问题(转)+(整理)
  • 原文地址:https://www.cnblogs.com/luogg/p/6794884.html
Copyright © 2011-2022 走看看