Spring基础总结

历史背景:

Spring总结 Spring是一个兴起于2003轻量级java开发框架. 它的最初目的:为了简化java EE企业级应用开发. 框架特点:

? Spring着重提供一种管理业务的对象方法.

? Spring全面的,模块化的,采用分层架构(因为不同的分层有不同的注解)

? Spring设计之初就是帮助你写出易于测试的代码.是一个测试驱动项目的理想框架.

? Spring是一个集成技术,得到广泛的认可. ? Spring不需要依赖任何框架,”一站式服务”. 框架优缺点:

优点:

1. Spring有效的组织中间层对象.

2. Spring消除很多项目中所常见的单例过度的使用.降低了可测试性和面向对象的程序。

3. Spring通过应用程序和项目之间一致的方法来处理配置.消除了自定义配置文件格式的烦恼.

4. Spring 通过针对接口而非类编码代价几乎为零,给编写者养成良好的编码习惯.

5. Spring在设计构建它之上的应用程序尽可能少依赖于SpringAPI.

6. 构建在Spring之上的应用程序易于单元测试.

7. Spring在你不使用EJB帮你解决很多问题.Spring能提供一种适用于很多应用程序的EJB的替代品.

8. Spring 使得是否使用EJB 成为实现时的选择,而非架构上的决定。

9. Spring 为数据访问提供了一个一致的框架

10. Spring 为很多方面提供了一种一致的简单的编程模型( JDBC、JMS、

JavaMail、JNDI)

11. Spring 是一种帮助你使用POJO 来构建应用程序的基础技术. 缺点:

Spring 中没有日志,没有连接池,没有分布式事务调度。

Spring做了些什么:

1.

2.

3.

4.

5. Spring主要目的是使J2ee更易于使用,培养好的编程习惯. Spring引用现有的资源,比如(log4j 连接池 分布式事务调用) Spring致力于现有技术更加易用,不与其他技术进行竞争. Spring 得益与内部一致性. Spring可用于各种应用服务器.

Spring分为6大块:

Core封装包是框架最基础部分,提供IOC和依赖注入特性

Spring基础总结

.

Context(上下文)封装包构筑于Core封装包的基础上,它提供了一种框架风格方式来访问对象.

Dao提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码.

ORM封装包提供了常用的对象/关系映射APIs的集成层.

AOP封装包提供了符合AOP Alliance 规范的面向方面的编程实现.

WEB包提供了基础的针对Web开发的集成特性.

MVC封装包提供了Web应用Model-view-Controller实现. Spring流程:

由客户端发送请求,经过Spring前控制器,前控制器把请求发送给自定义控制器,进行处理请求数据,根据请求数据创建ModelAndView

Spring基础总结

,然后根据请求响应

模型或页面给主控制器,主控制器根据模型进行验证,控制响应模型响应给主控制器,主控制器响应给客户端.

Spring MVC:

Spring的MVC围绕DispatchServlet设计,dispatch的作用是将请求分发到不同的处理器.

框架特点:

1. 清晰的角色划分:控制器,验证器,表单对象,命令对象,模型对

象,Servlet分发器,分发器映射,视图解析器.

2. 强大而直接的配置:框架类,应用程序类都使用javabean来配置.

3. 可适配,非侵入:simple型,command型,from型.

4. 可重用的业务代码:可以使用现有的对象作为表单或业务对象.

5. 可定制绑定和验证.

6. 可定制处理映射和页面决定.

7. 灵活的模型转换.通过Map来达到视图技术的集成.

8. 可定制本地化和主题解析:支持JSTL,Spring(from,tags)等标签

语言.

9.Spring Bean 的生命周期可以被限制在当前的HTTP Request 或者HTTP

Session。 准确的说,这并非Spring MVC 框架本身特性,而应归属于

Sping MVC使用的WebApplicationContext 容器。

Spring中的特殊Bean:

1. Controller(控制器).

2. Headler mapping(处理器映射)

3. View resolvers(视图解析器)

4. Local resolver(本地化解析器)

5. Theme resolver(Web主题解析器)

6. Multipart filed resolver(文件上传解析器)

7. Herdler Exception resolver (处理异常解析器)

Spring控制器:

1. Controller控制器.

2. 抽象的控制类abstractConlltroller(实现

handleRequestInternal(HttpServletRequest, HttpServletResponse)抽象方法)

3. 多方法控制类MultiMethodController(可以自定义方法名)

4. 表单控制器

5. 命令控制器

6. 向导型控制器.

Spring跳转方式:

?

? Redirect(丢失数据,重新提交表单路径) Forward(不丢失数据,执行当前路径) Spring视图解析:(这样保持应用程序的一致性视图页面)

<!-- 设置显示返回页面信息 -->

<bean id="viewResolver"

class="org.springframework.web.servlet.view.InternalResourceVi

ewResolver">

<!-- 设置文件前缀与后缀 -->

<property name="prefx" value="/" />

<property name="suffix" value=".jsp" />

</bean>

Spring标签:

两大标签:核心标签,from表单标签.

From表单标签:内部暴露一个path,绑定对象模型,命令模型 放

pageContext中去.

Errors标签:展现字段的错误,来自你关联控制器的验证器产生的错误途径. Spring标签:用于错误消息验证的绑定等等.

Spring验证器:

有两种方式:

1. 直接通过bindException 绑定错误对象.

2. 实现validator接口,通过IOC方式注入你要验证的Class在配置

Controller文件是进行property进行关联.

<bean name="/person.do"class="com.lxit.spring.controller.PersonController">

<property name="formView" value="/person.jsp" /> <property name="successView" value="/success.jsp" />

<property name="commandName" value="person" />

<property name="commandClass"value="com.lxit.spring.validator.Person" />

<property name="validator" ref="personValidator" />

</bean>

Spring的注解:

(通过DispatchServlet扫描映射方法,在Dispatch-servlet.xml加入组件配置)

<!-- 通过注解自动装配@Controller类,*号代表所有目录也包括子目录 --> <context:component-scan base-package="com.lxit.spring.*" />

类注解:@controller 指定类控制器 方法注解:

@RequestMapping(“/index.do”)映射一个请求路径.

@SessionAttrubutes()存储会话的属性.

@RequestMapping(value = "/getSession.do")

public String getSession(@ModelAttribute("session") User user) {

log.info("=======获取登录用户@ModelAttribute如下:==========");

log.info("用户名:"+ user.getUsername());

log.info("密码:"+ user.getPassword());

return "/success.jsp";}

@RequestParam()绑定地址栏传参方法和参数. @RequestMapping(value = "/getRequestParam.do", method = RequestMethod.GET) public String getRequestParam(

@RequestParam("username") String username,Model model) {

log.info("=======获取@RequestParam如下:==========");

log.info("用户名:"+ username);

model.addAttribute("username", username);

return "/success.jsp";}

}

? @ModelAttribute 当作为一个方法参数时@ModelAttribute 用于映射一个模

型属性到特定的注解的方法参数.

Spring-IOC-控制反转:

如何理解IOC:“不要打电话给我,我会打给你”

IOC与DI(依赖注入)是同一种理念

org.springframework.beans 及org.springframework.context 包是SpringIOC容器的基础. BeanFactory:擅长处理bean的配置和初始化与装载.

如何配置bean:

<bean id="helloBean1" class="com.lxit.spring.service.HelloBean" />

<!-- 导入系统资源配置文件 -->

星字符是通配符,两个**可以匹配应用程序下任何地方.

<import resource="applicationContext-*.xml"/>

<import resource="applicationContext-two.xml"/>

Bean 的命名:

Bean可以有多个ID或者一个ID,但是ID是唯一的,id与name是等价的.

bean的别名配置:

<alias name="helloBean" alias="hello"/>

ApplicationContext:在bean的功能之上,添加了更多功能 如AOP/事物处理.

1.

2.

3.

1. 应用上下文提供文本信息解析工具,包括国际化. 应用上下文提供了载入文件资源的通用方法,载入图片. 应用上下文可以注册为监听器的bean方法事件. ClasspathXMLApplicationContext::从类路径中的XML文件载入上下文定义信

息,把上下文定义文件当成类路径资源.也就是解析应用程序相对路径下的上下文XML.

2.

3. FileSystemXMLApplicationContext:与上面恰恰相反,解析绝对路径下面的XML文件. XMLWebApplicaionContext: 从WEB系统中的XML文件载入信息.

Classpath*:前缀:是查找应用程序路径下的applicationContext.xml.

File:前缀: 是file前缀来指定加载的配置文件信息. ApplicationContext有那些重要的子类:

自动装配(autowire)协作者:

注意:在spring2.5.6以后的本版中,不再需要指定autowire 属性,因为BeanFactory 会自动检查bean 关联关系:

五种类型:

1. No.

2. Byname根据名字进行装配.

3. Bytype根据类型进行装配.

4. Constructor根据构造进行装配.

5. Autodetect根据bean类的自省机制来决定使用构造

器还是类型进行方式,如果发现默认是构造器,那么

将使用bytype方式.

Spring依赖注入:

四种方式:

1. 接口注入方式:

-好处降低代码的耦合度,提高代码的可读性和操作性.

<!-- 配置接口注入Bean的实例,注入实例后调用初始化方法 --> <bean id="cbean" class="com.lxit.spring.controller.ClassBean"

init-method="init" />

2. 构造器注入方式:

-根据参数类型进行匹配,如果构造器参数类型定义明确,

bean定义的参数顺序就是构造器参数顺序.<配置信息如下> 有4种方式配置值

1.name属性 2.type:类型配置 3.index 下标指定4.ref引

用配置bean

<bean id="constructorbean1"

class="com.lxit.spring.controller.ConstructorBean">

<!-- 注入对象 进行引用 与构造器的参数进行对应 也可以通过下-->

<constructor-arg name="hellobean" ref="hello" /> <constructor-arg name="name" value="admin" /> <constructor-arg name="count" value="100" />

</bean>

3. Setter设值注入:

-调用bean的set方法,即可实现基于setter的依赖注入. 3种配置方式:1.配置当前上下文-local属性

2.配置应用程序的资源配置-bean

3.配置内部bean

<!-- <bean id="setterbean1" class="com.lxit.spring.controller.SetterBean">

local作用于当前上下文 <ref local="hello" /> </property>

</bean> -->

<bean id="setterbean2" class="com.lxit.spring.controller.SetterBean">

<!-- 作用于整个应用程序 --> <property name="hellobean"> <ref bean="hello"/> </property> </bean>

<<bean id="setterbean3" class="com.lxit.spring.controller.SetterBean"> 配置内部bean方法

<bean class="com.lxit.spring.controller.HelloBean"></bean> </property>

</bean>

Spring-bean作用域:

五种作用域:

1. singleton-单实例,多分发处理.

2. prototype-多实例.每来一个实例实例化一次.

3. Requrst –请求一次实例一次.

4. Session –基于session

5. Global Session-全局session.

Spring-bean生命周期:

1. 实例化bean.

2. 依赖注入,设置bean属性.

3. 实现了BeanNameAware,调用setBeanName,

获取当前Bean的ID.

4. 实现了BeanFactoryAware,调用

setBeanFactory,获取当前上下文的bean对象.

5. 初始化bean.实现了InitializingBean.

6. 初始化自定义init方法.

7. 处理当前bean前面的bean配置.

postProcessBeforeInitializatio

8. 处理当前bean之后的bean的配置. postProcessAfterInitializatio

9. 调用系统的destroy()进行销毁.

10. 调用自定义销毁方法. Spring-集合注入:

4种集合:

1) List集合:

<!-- 配置集合对象 -->

<property name="someList"> <list> <value>${system.name}</value> <ref bean="object" /> <ref bean="singleton" /> <ref bean="singleton" /> </list>

</property>

2)Set集合:

<!-- 配置set对象 --> <property name="someSet"> <set> <value>${system.name}</value> <ref bean="object" /> <ref bean="singleton" /> <ref bean="singleton" /> </set> </property>

3)Props(资源文件):

<bean id="config"

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="locations"> <value>classpath:resources.properties</value> </property>

</bean>

<!-- 设置键值当实例化的时候使用 不然不进行加载 -->

<bean id="prosService" class="com.lxit.spring.service.PropsService" lazy-init="true"> <property name="properties"> <props> <prop key="sid">${system.name}</prop> <prop key="username"></prop> <prop key="count">123</prop> <!-- 资源文件进行控制开关 --> <prop key="sys.log">${sys.log}</prop> </props> </property></bean>

4)Map(键值对):

<!-- 配置map对象 key字段必须指定Value属性 --> <property name="someMap"> <map> <entry> <key> <value></value> </key> <value></value> </entry> <entry key="hello" value="你好世界!" /> </map> </property>

集合的合并:

从2.0 开始,Spring IoC 容器将支持集合的合并。这样我们可以定义parent-style和child-style 的<list/>、<map/>、<set/>、<property/>或<props/>元素,

子集合的值从其父集合继承和覆盖而来;也就是说,父子集合元素合并后值就是子集合中的最终结果,而且子集合中的元素值将覆盖父配置中对应的值.

组合属性注入:

子类可以给父类的属性赋值(在子类中引入父类并生成

get(),set()。然后在bin的身体里面通过<property>来指定) Spring-注解:

隐形加载方式:

1. AutowiredAnnotationBeanPostProcessor:自动扫描注解处理类?

2.CommonAnnotationBeanPostProcessor:组件注解处理类

3. PersistenceAnnotationBeanPostProcessor:持久化注解处理类

4.RequiredAnnotationBeanPostProcessor:检查/验证注解处理类

属于java规范的注解有:

@Resource(相当于autowired)

@PostConstruct(指定自定义方法初始化)

@PerDestroy(指定自定义销毁方法)。

Spring注解:

@component组件做了最基本的事情,把类转为组件实例 组件可以实现通用的方法和共同的逻辑,注解是依赖于组件的

@Controller、@Service,@Repositroy分别对应了控制层、服务层、持久化层

@Scope可以用来指定singlethon、prototype、request、session、global session五大作用域

使用过滤器自定义扫描:我们可以通过context-component-scan的include-filter和exinclude-filter来进行添加,每个过滤器都必须有 <type>、<expression>属性,我们用到的过滤器有regex、annotation等

@Autowired注解可以用于:

1.

2.

3. 设值注解:通过set方法注入 构造注解:通过构造方法注入 多参数注解:通过以属性为参数的方法

我们可以在@Autowired注解的括号里指定required=false,也就是你当前注入的实例存不存在都可以

@Autowired可以注入bean容器

@Qualifier注解:可以帮我们指定注入的实例,这个注解也可以被指定为构造器的参数和方法的参数

Spring –AOP(面向切面编程):

AOP在formWork的作用:

1. 提供声明式企业服务,为了替代EJB的声明式服务,

最重要的服务是声明性事务管理.

2. 允许用户实现自定义切面,用AOP来完善OOP使用.

AOP的组成与概念:

1. 切面(aspect):一个关注点的模块化,这个关注点可以横切多个对象.

2. 连接点(joinpoint):连接点建立在切面的基础之上,是程序执行过程中某个特定的点.

3. 通知(advice):在切面的某个特定的连接点上的执行的动作.

a) 前置通知:某个连接点之前执行的通知.

b) 后置通知:某个连接点执行之后的通知.

c) 异常通知:当执行某个连接点出现了异常的通知.

d) 最终通知:当某个连接点退出执行的通知(不管是否出现异常)

e) 环绕通知:包围一个连接点,环绕包括前置和后置.

4. 切入点(poincut):匹配连接点的断言,切入点建立在连接点基础之上

切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用Aspect切入点语法.

通过切入点匹配连接点的概念是AOP 的关键

5. 引入:用来给一个类型声明额外的方法和属性.

6. 目标对象:被一个切面和多个切面通知的对象.

7. AOP代理:用来实现切面契约.

分为动态jdk代理(有接口)cglib代理(只有实体类).

8. 织入:也就是目标转移,把切面连接到其他应用程序或对象上.

Spring-AOP代理:

代理的基础:

ProxyFactoryBean引入一个间接层,通过getObject()创建一个代理.

使用ProxyFactoryBean的好处,切入点和连接点通过Ioc来进行管理.

proxyFactoryBean的属性:

? ProxyInterfances:代理接口.

? interceptorNames:代理拦截的bean,顺序是优先级的划分,排在前面优先级别高.

? 单例:工厂返回同一个对象,不管getObject()调用的频繁,如果你想使现有状态变成多例,那么你就

scope设置为prototype来使用原型通知.

上述示例如下:

<!-- 配置你好代理服务类 -->

<bean id="helloTarget" class="com.lxit.spring.service.HelloService" /> <bean id="helloAdvice" class="com.lxit.spring.service.HelloAdviceService" />

<bean id="helloService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target">

<ref local="helloTarget" />

</property>

<property name="proxyInterfaces">

<value>接口路径</value>

</property>

<property name="interceptorNames">

<list>

<value>helloAdvice</value>

</list>

</property>

</bean>

配置JavaBean属性:

都是从org.springformwork.aop.fromwork.proxyConfig继承而来.这个类是spring所有AOP代理工厂类的父类.

? proxyTargetClass:定义目标代理类.

? Optimize:主要是给CGLIB做优化策略.

? Frozen:如果一个代理类是Frozen,就不允许配置被修改. ? ExposeProxy:暴露当前代理的线程.

? AopProxyFactory:自定一种方法是否进行动态代理.

JDK与CGLIB代理的区别:

Spring缺省使用JDK动态代理作为AOP的代理,Spring也可以使用CGLIB代理,只要把ProxyFactoryBean的属性

proxyTargetClass设置为“true“就可以使用CgLIB进行代理. 代理是按实所取,如果代理的类没有实现接口使用CGLIB代理,如果你使用了接口并进行代理,那么你就使用JDK动态代理. 代理注意以下几点:

不能代理final修饰的方法,因为不能被覆盖.

使用CGLIB需要类路径有CGLIB 2库,使用JDK需要JDK就行. 使用接口代理配置如下:

<!-- 配置个人服务、通知代理类,使用接口代理 -->

<bean id="personTarget" class="com.lxit.spring.service.PersonServiceImpl" /> <bean id="personAdvice" class="com.lxit.spring.service.PersonAdviceService" /> <bean id="personService"class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces">

<value>com.lxit.spring.service.PersonService</value>

</property>

<property name="target">

<ref local="personTarget" />

</property>

<!-- *号通配符,匹配应用所有ID名称 -->

<property name="interceptorNames">

<list>

<value>personAdvice</value>

</list>

</property>

<!-- 设为true基于CGLIB的代理将创建 -->

<property name="proxyTargetClass">

<value>true</value>

</property>

<!-- ThreadLocal可目标对象访问 -->

<property name="exposeProxy">

<value>true</value>

</property>

</bean>

AOP自动代理:

1. 自动代理(类)

我们可以使用ProxyBeanFactory配置属性,如果bean有很多,无疑是给编码带来了繁重的业务,使用自动代理类,只需要根据Bean的名字进行匹配后自动代理的解决方法.

<!-- 配置购买商品自动代理服务类 -->

<bean id="shoppingService"

class="com.lxit.spring.service.ShoppingService" />

<bean id="shoppingAdvice"

class="com.lxit.spring.service.ShoppingAdviceService" />

<bean class="org.springframework.aop.framework.autoproxy

.BeanNameAutoProxyCreator">

<property name="beanNames">

<!—只要bean的名字后缀为Service都进行代理通知 -->

<value>*Service</value>

</property>

<property name="interceptorNames">

<list>

<value>shoppingAdvice</value>

</list>

</property>

</bean>

2. 自动代理(method)

使用自动代理method,可以指定你的目标方法之上,更清晰的控制目标.代理目标.

org.springframework.aop.support.NameMatchMethodPointcutAdvisor 类是最基本的pointcutAdcice. 它是Spring 中静态Pointcut 的实例.

<!-- 配置操作日志自动代理服务类 -->

<bean id="userService"

class="com.lxit.spring.service.UserService" /> <bean id="logAdvice"

class="com.lxit.spring.service.LogAdviceService" /> <bean class="org.springframework.aop.framework.autoproxy

.DefaultAdvisorAutoProxyCreator" />

<bean class="org.springframework.aop.support

.NameMatchMethodPointcutAdvisor">

<property name="advice" ref="logAdvice" />

<property name="mappedNames">

<list>

<value>*add*</value> <value>*delete*</value> <value>*update*</value> <value>*find*</value>

</list>

</property> </bean>

AOP- 注解:

AspectJ配置的应用: <!-- 配置你好切面服务类-->

<bean id="helloAspect"

class="com.lxit.spring.service.HelloAspectService" />

<bean id="helloService"

class="com.lxit.spring.service.HelloService" />

<aop:config>

<aop:aspect id="myAspect" ref="helloAspect">

<!-- 1.*星代表返回参数; 2.*星代表所有的类; 3.*星代表所有的方法 -->

<aop:pointcut id="myService"

expression="execution(* com.lxit.spring.service.*.*(..))" /> <aop:before pointcut-ref="myService" method="doBefore" />

<aop:after pointcut-ref="myService" method="doAfter" />

</aop:aspect>

</aop:config>

@AspectJ注解的应用:切面必须是Spring的bean.

@Aspect

@Service

public class AccountAspectService.

@Pointcut切入点:@pointcut 声明切入点与@before @after一起配合使用.

//声明切入点

@Pointcut("execution(public * *(..))")

public void log() {}

// 切入后通知目录方法

@Before("log()")

public void log(JoinPoint jp) {

log.info("正在记录操作日志:----------------"); log.info("类="+ jp.getTarget().getClass().getName() +"方法=" + jp.getSignature().getName());

}

切入点函数:

分为四种:

? 方法切点函数:通过描述目标类方法信息定义连接点.

?

? execution(* log(..))表示所有目标类中的log()方法. @annotation(com.lxit.spring.Geren) 表示任何标注了@NeedTest

Spring基础总结

解的目标类方法

? 方法入参切点函数:通过描述目标类方法入参的信息定义连接点.

? args(com.lxit.spring.User)表示所有有且仅有一个按类型匹配于User

的入参的方法。

? @args()通过判别目标方法的运行时入参对象的类是否标注特定

? 目标类切点函数:通过描述目标类类型信息定义连接点.

? within(com.lxit.spring.service.*Service) 表示在

com.lxit.spring.service 包中,所有以Service 结尾的类的所有连接点。

? target(com.lxit.spring.User)定义的切点,User、以及User 实现类

SubUser 中所有连接点都匹配该切点。

? 代理类切点函数:通过描述目标类的代理类的信息定义连接点.

? this()代理类按类型匹配于指定类,则被代理的目标类所有连接点匹配切

组合式表达式:

inPublic:(在一个方法执行连接点代表了任意public 方法的执行时匹配).

inService:(在一个代表了在服务模块中的任意的方法执行时匹配)

inServiceAndPublic:(在一个代表了在服务模块中的任意公共方法执行匹配)。 通知(Advice):

传递参数给通知通过args来进行绑定:

@Before("execution(* com.lxit.spring.service.RegisterService.register(..)) && args(user)")

前置通知:

//前置通知

@Before("execution(* com.lxit.spring.service.LoginService.welcome())")

public void before() {

log.info("2.欢迎在线登录用户...");

}

后置通知:

//后置通知:获取返回参数

@AfterReturning(value="execution(* com.lxit.spring.service.LoginService.*(..))", returning="name")

public void afterReturning(Object name) {

log.info("3.获取"+ name +"的角色与权限...");

最终通知:

//最终通知: *1代表返回类型;*2代表方法;(..)代表方法参数

@After("execution(* com.lxit.spring.service.LoginService.*(..))")

public void after() {

log.info("2.登录成功,正在进入系统...");

}

异常通知:@ExpectedException(Exception.class) 知有异常,为单元测试类通过,并捕获异常 //异常通知

@AfterThrowing("execution(

* com.lxit.spring.service.LoginService.exce(..))")

public void afterException(JoinPoint jp) {

log.info("2.正在记录异常错误信息如下:----------------");

log.info("类="+ jp.getTarget().getClass().getName()

+"方法=" + jp.getSignature().getName());

}

//获取具体的异常信息,写入数据库中...

@AfterThrowing(value="execution(

* com.lxit.spring.service.LoginService.exce(..))", throwing="ex")

public void afterException2(JoinPoint jp, Exception ex) {

log.info("3.异常错误原因信息如下:----------------");

log.info(ex.getMessage());

环绕通知:通知的第一个参数必须是ProceedingJoinPoint 类型。在通知体内,调用

ProceedingJoinPoint 的proceed()方法会导致后台的连接点方法执行 //环绕通知

@Around("execution(

* com.lxit.spring.service.LoginService.around(..))")

public Object around(ProceedingJoinPoint jp) throws Throwable {

log.info("1.启动环绕通知,调用目标业务方法...");

//获取参数,业务处理.

Object[] args = jp.getArgs();

log.info("2.当前访问参数值为>:"+ args[0]);

Object result = jp.proceed(new Object[]{"ADMIN"});

log.info("4.结束环绕通知,记录目标业务方法...");

return "[ "+result+" ]我是管理员.";