Spring学习(二)

Spring

AOP

  • 什么是AOP
    AOP(Aspect Oirented Programming),即面向切面编程,可以利用AOP对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的重用性以及开发效率。通俗的讲:AOP可以实现在不修改源码的基础上,在主干功能中添加新功能。
    如在原有的登录逻辑上添加权限判断(是否管理员)时,不使用AOP可能要去原有代码逻辑中添加判断语句修改,而使用AOP可以不修改源代码从而添加权限判断模块来完成。

  • AOP的底层原理
    AOP的底层使用动态代理模式。当被代理类存在被代理类接口时,使用JDK动态代理创建接口实现类代理对象,来实现AOP。当被代理类没有实现被代理类接口时,使用CGLIB动态代理创建子类的代理对象。

  • JDK动态代理
    由静态代理可知,动态代理的关键之处有两点:
    - 如何根据被代理类对象动态的创建出代理类对象:使用Proxy.getProxyInstance(ClassLoader loader , Class<?>[] interfaces ,InvocationHandler handler)方法
    - 如何使用代理类动态的调用被代理类中的方法:使用InvocationHandler接口的实现类

//被代理类接口
public interface User{
	void login();

	void regist();
}

//被代理类
public class UserImpl{
	@Override
	public void login(){
		System.out.print("login方法");
	}

	@Override
	public void regist(){
		System.out.print("regist方法");
	}
}

//使用ProxyFactory工厂类创建动态代理对象
public class ProxyFactory{
	public Object getProxyInstanc(Object object){
		MyInvacationHandler handler = new MyInvocationHandler();
		handler.bind(object);
		return Proxy.newProxyInstance(object.getClass().getClassLoader,object.getClass().getInterfaces(),handler);
	}
}


//使用InvocationHandler实现类完成方法的调用
public class MyInvocationHandler implements InvocationHandler{
	private Object object = null;
	public void bind(Object object){
		this.object = object;
	}

	public Object invoke(Object proxy , Method method , Object[] args) throws Throwable{
		//执行一些需要优化的操作
		//print(...)		
		Object object  =  method.invoke(obj , args);
		//执行一些需要优化的操作
		return object;
	}
}
  • AOP中的一些术语

    • 连接点:指的是类中那些方法可以被增强,这些方法就被称之为连接点

    • 切入点:指的是实际真正被增强的方法,称为切入点

    • 通知(增强):实际增强的逻辑部分称为通知(增强)
      通知有多种类型,分为:

      • 前置通知
      • 后置通知
      • 环绕通知
      • 异常通知
      • 最终通知(类似于finally,是一个无论如何都会执行的通知)
    • 切面:是一个动作,指的是把通知应用到切入点的全过程

  • AspectJ框架
    AspectJ框架不是Spring的组成部分,他是一个独立的AOP框架,一般把AspectJ框架和Spring一起使用进行AOP操作。基于AspectJ实现AOP操作可以通过注解方式和XML配置文件方式实现。

  • 切入点表达式:用于告知Spring对哪些类中的哪些方法进行增强,格式为:
    execution([权限修饰符][返回类型][类全路径][方法名]([参数列表])),如execution(* com.jarvis.dao.UserDao.login(..))

  • 基于AspectJ注解实现AOP操作

    • 创建增强类和被增强类 ,并添加自动创建对象注解(@Component注解等)
    • 在XML文件中进行开启组件扫描<context:component-scan base-package=""></context:component-scan>
    • 在增强类上添加注解@AspectJ,表示Spring将使用该类生成代理对象
    • 在XML文件中开启生成代理对象:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    • 配置不同类型的通知(使用不同的注解对代理类中的不同方法进行标注)
      • @Before(value=“切入点表达式”):前置通知注解
      • @After:代表最终通知注解
      • @AfterReturning:代表后置通知注解
      • @AfterThrowing:异常通知注解
      • @Around:环绕通知注解
@Component
@AspectJ
public class UserProxy{
	//前置增强
	@Before(value="execution(* com.jarvis.bean.User.login(..)")
	public void before(){}

	//后置增强
	@AfterReturning(value="execution(* com.jarvis.bean.User.login(..)")
	public void afterReturning(){}

	//环绕增强,这个方法有些不同,需要在参数列表中添加参数ProceedingJoinPoint
	@Around(value="execution(* com.jarvis.bean.User.login(..)")
	public void around(ProceedingJoinPoint point){
		//环绕前置通知操作
		point.proceed();
		//环绕后置通知操作
	}

	//异常通知
	@AfterThrowing(value="execution(* com.jarvis.bean.User.login(..)")
	public void afterThrowing(){}

	//最终通知
	@After(value="execution(* com.jarvis.bean.User.login(..)")
	public void after(){}
}
  • 抽取相同的切入点
    当有多个通知需要添加到相同的切入点时,我们可以自定义一个方法来将这个切入点抽取出来,使用到@Pointcut注解,当使用这个切入点时,使用该方法名代替即可:
@Pointcut(value="execution(....)")
public void pointForBalaBala(){}

@Before(value = "pointForBalaBala()")
public void before(){}
  • 对多个增强类设置增强类优先级
    当有多个类对同一切入点进行增强时,可以使用@Order(数字类型value)注解对他们进行优先级设置,value越小优先级越高

  • 完全注解开发
    只需要创建配置类实现开启组件扫描以及开启生成代理类即可,添加以下注解即可完成完全注解开发:

    • @Configuration
    • @ComponentScan
    • @EnableAspectJAutoProxy(proxyTargetClass=true)
  • 使用配置文件实现AOP
    其实使用配置文件实现AOP也非常简单,只需要在配置文件中完成以下步骤即可:

    • 配置增强类和被增强类的Bean管理
    • 开启组件扫描和代理类生成
    • 设置切入点和切面
<bean id="user" class=""></bean>
<bean id="userProxy" class=""></bean>

<context:component-scan base-packages=""></context:compnent-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

<aop:config>
	<!-- 设置切入点 -->
	<aop:pointcut id="point1" expression="execution(...)">
	<!-- 设置切面 -->
	<aop:aspect id="aspect1" ref="userProxy">
		<!-- 设置通知 -->
		<aop:before method="" point-ref="point1"/>	
	</aop:aspect>
<aop:config>

JdbcTepmlate

  • JdbcTemplate的概念梳理
    什么是JdbcTemplate,是Spring框架对JDBC进行封装,使用其方便实现对数据库的操作。也就是说,他相当于完成了两方面的封装

    • JDBCUtils:也即使用数据库连接池获取数据库连接(properties====》dataSource =====》Connection)并对其该数据库连接进行操作的过程
    • BaseDAO:即使用DBUtils来对数据库连接进行操作的过程(QueryRunner=====》操作sql语句)

    在使用JDBCTemplate时,我们只需要在XML配置文件中完成对数据库连接池的配置,以及对JDBCTemplate对象Bean管理的配置,这样就可以使用IOC+JDBCTemplate对数据库进行操作了:

<!-- 当然也可以使用之前提到过的context:property-placeholder获取外部文件的方式 -->
<bean id="dataSource" class="...">
	<property name="driverClassName" value=""></property>
	<property name="username" value=""></property>
	<property name="url" value=""></property>
	<property name="password" value=""></property>
</bean>

<bean id="jdbcTemplate" class="">
	<property name="dataSource" ref="dataSource"></property>
</bean>
  • 使用JdbcTemplate操作数据库

    • 更新操作:使用JdbcTemplate对象的update(String sql , Object…args)方法,传入SQL语句及sql注入参数即可
    • 查询操作:根据不同的需求可以使用不同的方法:
      • 查询返回某个值:如查询COUNT(*),可以使用JdbcTemplate对象的queryForObject(String sql , Class<T> requiredType)方法——queryForObject(sql,Integer,class)
      • 查询返回对象:使用JdbcTemplate对象的重载方法queryForObject(String sql , RowMapper<T> rowMapper, Object...args),如User user = queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),id);
      • 查询返回集合:使用JdbcTemplate对象的query(String sql , RowMapper<T> rowMapper, Object...args),如List<User> list = query(sql,new BeanPropertyRowMapper<User>(User.class),id);
  • 使用JdbcTemplate批量操作数据库
    当一次所需执行相同操作的数据量较大时,可以使用批量操作方法batchUpdate(String sql , List<Object[]> args),参数sql为SQL语句,args为需要批量操作的多组sql注入值。一般来说,使用批量操作进行添加删除时会更加方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值