关于面试别问及Spring如何回答思路总结!
首先要知道 Spring两大核心IOC和AOP(Java轻量级业务层框架Spring两大核心IOC和AOP原理)
IOC:
1.从Java最基本的创建对象开始
如Interface Driven Design接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执行:AInterface a = new AInterfaceImp(); 这样一来,耦合关系就产生了,如:
classA
{
AInterface a; A(){} AMethod()//一个方法
{
a = new AInterfaceImp();
}
}
InterfaceImplFactory
{
AInterface create(Object condition)
{
if(condition == condA)
{
return new AInterfaceImpA();
}
else if(condition == condB)
{
return new AInterfaceImpB();
}
else
{
return new AInterfaceImp();
}
}
}
Filter的实现、interceputor的实现以及struts2的拦截器的实现都是AOP思想的体现
下面一个例子来说明问题
引用于:http://supben.iteye.com/blog/1520126
package com.supben.advice; import java.lang.reflect.Method; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice; /**
* 实现spring advice 接口
*
* @author shencl
*
*/
public class TestAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice { private static final Logger log = LoggerFactory.getLogger(TestAdvice.class); /**
* before 通知
*/
public void before(Method method, Object[] args, Object target) throws Throwable {
log.info(target.getClass().getSimpleName() + "类的" + method.getName() + "方法,执行TestAdvice的before通知");
// 通知要做的业务
if (method.getName().startsWith("get")) {
log.info("只有方法名是以get开始的方法,才会执行到这句话....");
}
} /**
* after 通知
*/
public void afterReturning(Object arg0, Method method, Object[] arg2, Object target) throws Throwable {
log.info(target.getClass().getSimpleName() + "类的" + method.getName() + "方法,执行TestAdvice的after通知");
} /**
* 异常通知
*/
public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {
log.info(target.getClass().getSimpleName() + "类的" + method.getName() + "方法,执行TestAdvice的throwing通知");
} }
配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <context:annotation-config />
<!-- 扫描com.supben 下所有的包-->
<context:component-scan base-package="com.supben" /> <bean id="testAdvice" class="com.supben.advice.TestAdvice" />
<aop:config>
<aop:advisor pointcut="execution(* *..service.*Service.*(..))"
advice-ref="testAdvice" />
</aop:config> </beans>
service接口
package com.supben.service;
public interface FirstService {
public void get();
public void exception();
}
service实现类
package com.supben.service.impl; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import com.supben.service.FirstService; @Service("firstService")
public class FirstServiceImpl implements FirstService {
private static final Logger log = LoggerFactory.getLogger(FirstServiceImpl.class); public void get() {
log.info("方法执行ing.....");
} public void exception() {
throw new RuntimeException("测试异常");
}
}
测试类
package com.supben.test;
import junit.framework.TestCase;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.supben.service.FirstService;
import com.supben.spring.SpringContextUtil;
public class ServiceTest extends TestCase {
/**
* 装载spring 配置文件
*/
static {
new ClassPathXmlApplicationContext("application.xml");
}
@Test
public void testGet() {
FirstService service = SpringContextUtil.getBean("firstService");
service.get();
}
@Test
public void testGet2() {
FirstService service = SpringContextUtil.getBean("firstService");
service.exception();
}
}
测试结果:
2012-05-09 15:10:10,028 INFO [com.supben.advice.TestAdvice] - FirstServiceImpl类的get方法,执行TestAdvice的before通知
2012-05-09 15:10:10,030 INFO [com.supben.advice.TestAdvice] - 只有方法名是以get开始的方法,才会执行到这句话....
2012-05-09 15:10:10,032 INFO [com.supben.service.impl.FirstServiceImpl] - 方法执行ing.....
2012-05-09 15:10:10,032 INFO [com.supben.advice.TestAdvice] - FirstServiceImpl类的get方法,执行TestAdvice的after通知
2012-05-09 15:10:10,035 INFO [com.supben.advice.TestAdvice] - FirstServiceImpl类的exception方法,执行TestAdvice的before通知
2012-05-09 15:10:10,035 INFO [com.supben.advice.TestAdvice] - FirstServiceImpl类的exception方法,执行TestAdvice的throwing通知
结果分析:
get方法满足执行之前会 执行 before通知,执行完成后会执行after通知。
exception方法执行之前会执行before 通知,因为方法名不是以get开头,所以不会执行before通知的业务逻辑。然后出现异常了会执行throwing通知,因为出异常了,方法没有执行完毕,所以不会触发after通知。
概念:
切面(aspect):
翻译成外貌更合适:整个程序相当于一个密封的圆柱体,即一个外貌,现在要面向这个东西编程,在不改变原来类(FirstServiceImpl)的情况下,改变里边的代码。通知(advice):TestAdvice里边的before,after,throwing方法都是通知。
常见的有前置通知,后置通知,异常通知。
切点(cut-point):定义通知应该应用在哪些地方,本例是FirstServiceImpl中的get方法和exception方法,一般用正则表达式定义。
切点表达式:配置文件中的execution(* *..service.*Service.*(..))
是一个切点表达式,表示的是一个一个的方法.比如本例中的表达式,意思是 包目录的最后一级是service,类/接口名 后缀为Service的
class文件里的,方法名为任意名称,参数个数不限的 方法。 * 表示任意,(..)表示方法参数个数不限。
目标对象(traget):FirstService就是目标对象。
此外还有两个重要的概念
引入(Introduction):允许为已存在类添加新方法和属性。
代理(Proxy):将通知应用到目标对象后创建的对象。
关于面试别问及Spring如何回答思路总结!的更多相关文章
- BAT面试官告诉你如何回答你的职业规划
前言(Why) 在面试中不论是在一面二面三面这种技术面,还是在最后的hr面,经常会被人问及,"谈谈你的职业规划"这种问题,我们回答的很可能会给我们的面试表现加分,如果回答地不好,对 ...
- 面试常问Spring IOC,不得不会。
广义的 IOC IoC(Inversion of Control) 控制反转,即“不用打电话过来,我们会打给你”. 两种实现: 依赖查找(DL)和依赖注入(DI). IOC 和 DI .DL 的关系( ...
- java web方面的面试问题,Spring MVC方面的面试问题,摘自java web轻量级开发面试教程
本文摘自java web轻量级开发面试教程: https://baike.baidu.com/item/Java%20Web%E8%BD%BB%E9%87%8F%E7%BA%A7%E5%BC%80%E ...
- 面试官:“谈谈Spring中都用到了那些设计模式?”。
我自己总结的Java学习的系统知识点以及面试问题,已经开源,目前已经 41k+ Star.会一直完善下去,欢迎建议和指导,同时也欢迎Star: https://github.com/Snailclim ...
- 《PHP程序员面试笔试宝典》——如何回答算法设计问题?
如何巧妙地回答面试官的问题? 本文摘自<PHP程序员面试笔试宝典> 程序员面试中的很多算法设计问题,都是历年来各家企业的"炒现饭",不管求职者以前对算法知识掌握得是否扎 ...
- 《PHP程序员面试笔试宝典》——如何回答快速估算类问题?
如何巧妙地回答面试官的问题? 本文摘自<PHP程序员面试笔试宝典> 有些大企业的面试官,总喜欢出一些快速估算类问题,对他们而言,这些问题只是手段,不是目的,能够得到一个满意的结果固然是他们 ...
- 《PHP程序员面试笔试宝典》——如何回答非技术性问题?
如何巧妙地回答面试官的问题? 本文摘自<PHP程序员面试笔试宝典> 评价一个人的能力,除了专业能力,还有一些非专业能力,如智力.沟通能力和反应能力等,所以在IT企业招聘过程的笔试.面试环节 ...
- 《PHP程序员面试笔试宝典》——如何回答技术性的问题?
如何巧妙地回答面试官的问题? 本文摘自<PHP程序员面试笔试宝典> 程序员面试中,面试官会经常询问一些技术性的问题,有的问题可能比较简单,都是历年的面试.笔试真题,求职者在平时的复习中会经 ...
- 基于spring的placeholder思路处理配置信息敏感信息加密解密的实践
基于Spring的placeholder处理思路,实现系统配置信息敏感信息的加密解密处理. 我们的处理方案,是基于类org.springframework.beans.factory.config.P ...
随机推荐
- linux/unix 编程手册 fork()函数
父进程通过fork()函数创建子进程,将父进程数据段和栈的内容拷贝到子进程中,子进程执行程序execve创建新程序,调用exit函数退出到等待wait(),挂起父进程, 父子进程享用相同的程序文本段. ...
- Leetcode: Valid Word Abbreviation
Given a non-empty string s and an abbreviation abbr, return whether the string matches with the give ...
- LinuxStudyNote
LinuxStudyNoteBy_Silvers:(E:\Video_Tutorials\Linux自学视频\linux视频教程-后盾网视频教程)22:25 2016/1/28============ ...
- java布局学习 (三)
前文已经讲了常用的4个布局了,今天再介绍最后的三个布局: 5.CardLayout 6.BoxLayout 7.空白布局null (五)CardLayout 纸牌布局 首先这种布局不是二维布局,而 ...
- 关于成为Java高级工程师之路
简单说明一下现状,个人目前学习使用java已经一年半,很迷茫,高不成低不就,在此列一个目标,为期18个月,再来个一年半,这样软件生涯三年后,我必须成为高级工程师! 这里涉及Java各个方面的知识,有的 ...
- 用Swift语言做App开发之单元测试
作为一个有质量保障的应用程序,当然少不了单元测试:Swift开发的App也亦如此,此文将以一个简单的实例来介绍Swift中的单元测试. 这里我们使用XCode模版自带的XCTest框架,此框架包含了一 ...
- 妈妈再也不担心我的编码问题了。中文编码融汇贯通,windows,django,python,java,html 【转】
http://blog.csdn.net/farmer_cc/article/details/41830999 HTML编码:html文件是utf-8编码的,不确定的话用记事本打开,另存为的时候就能够 ...
- Apache JMeter安装
Apache JMeter安装说明 1. 安装环境要求: Java版本 JMeter要求充分满足JVM1.3或更高. 操作系统 JMeter可以在当前任何一个已经部署了Java的操作系统上 ...
- view向上滚动
之前本来是打算做TextView垂直向上滚动的,后来发现一位大神做得很好,https://github.com/sfsheng0322/MarqueeView 孙福生大神,然后自己要用到多个View向 ...
- wex5 实战 图片触摸放大移动插件easyzoom的使用与集成
一 前言 客户的需求就是上帝的召唤. 作为一个开发人员,或者软件从业者,客户的要求就是准则. 遇到一个客户,让我做一个图片放大,但是移动拖拽要定位精准.之前研究过一个hammer插件,多次尝试放大后的 ...