Java Spring 两大特色
引言
本文主要描述的是Spring常用的两大特色功能:AOP和IoC容器
Spring框架的优点:
- 低侵入式设计,代码污染低
- Spring容器降低了业务兑现滚铁环的复杂性,提高了组件之间的解耦
- SpringAOP支持允许将一些通用任务进行集中处理
- Spring的ORM和DAO提供了与第三方持久化框架的良好整合,并简化了底层的数据库访问
- Spring的高度开发性
IoC
Spring的IoC:就是常说的“控制反转”,也又叫依赖注入的(DI)。
优点:IoC最大的好处就是把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变得很简单(说的是基于接口的编程),只需要修改XML就可以了,这样我们不用重新编译即可运行,甚至可以实现对象的热插拔。
缺点:由于对象的生成使用了反射编程,所以也给它带来了影响效率的缺点,但是相对于它能提高可维护性和灵活性,这点损耗也就不算什么了,除非对效率要求特别高。
AOP
Spring的AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。
主要功能:Authentication 权限、Caching 缓存、Context passing 内容传递、Error handling 错误处理、Lazy loading 懒加载、Debugging 调试、logging 日志记录、Transactions 事务等
AOP 相关概念
方面(Aspect)、连接点(joinpoint)、通知(advice)、切入点(pointcut)、引入(introduction)、aop代理
1. 配置切面:config
xml配置:
<!-- 声明业务类 --> <bean id="userService" class="com.aop.UserService" > <property name="name" value="jamin Huang"></property> </bean> <!-- 声明通知类 --> <bean id="aspectBean" class="com.aop.aspect.AopAdvice" />
2. 声明:pointcut
xml配置方式:
<aop:config> <aop:aspect ref="aspectBean" > <aop:pointcut expression="execution(* com.aop.*Service.*(..))" id="pointcut"/> </aop:aspect> </aop:config>
注解方式:
@Pointcut("execution(* com.annotation.aop.*Service.*(..))") public void pointcut() {}
3. 通知:advice
前置通知 before
xml方式:
<aop:before method="before" pointcut-ref="pointcut" />
/*前置通知*/ public void before(JoinPoint jPoint) { System.out.println("这里是前置通知"); }
注解方式:
@Before("pointcut()") public void before() { System.out.println("Before."); }
返回后通知 after-returning
xml方式:
<aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="result" />
/*后置返回通知*/ public void afterReturn(JoinPoint jPoint, String result) { System.out.println("这里是后置返回通知,返回值result:" + result); }
注解方式:
@AfterReturning(pointcut="pointcut()", returning="returnValue") public void afterReturning(Object returnValue) { System.out.println("afterReturning : " + returnValue); }
抛出异常后通知 after-throwing
xml方式:
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="ex" />
/*抛出异常通知*/ public void afterThrowing(JoinPoint jPoint, Exception ex) { System.out.println("这里是抛出异常通知,抛出异常:" + ex.getMessage()); }
注解方式:
@AfterThrowing(pointcut="pointcut()", throwing="ex") public void afterThrowing(RuntimeException ex) { System.out.println("afterThrowing : " + ex.getMessage()); }
后通知 after
xml方式:
<aop:after method="after" pointcut-ref="pointcut" />
/*后置通知*/ public void after(JoinPoint jPoint) { System.out.println("这里是后置通知"); }
环绕通知 around
xml方式:
<aop:around method="around" pointcut-ref="pointcut" />
/*环绕通知*/ public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("======执行环绕通知开始========="); // 调用的方法名 String method = pjp.getSignature().getName(); // 获取目标对象 Object target = pjp.getTarget(); // 执行完方法的返回值 // 调用proceed()方法,就会触发切入点方法执行 Object result=pjp.proceed(); System.out.println("输出,方法名:" + method + ";目标对象:" + target + ";返回值:" + result); System.out.println("======执行环绕通知结束========="); return result; }