Spring 特性与应用
重点掌握IOC(控制反转)、AOP(面向切面)
什么是Spring
Spring 是由Rod Johnson创建的轻量级容器,目的在于简化企业级开发。
Spring 就是管理bean的容器框架。
Spring的特性
轻量级 相对于EJB而言Spring是轻量级的容器,不依赖任何web容器。
容器 Spring本身不具备任何功能,仅仅是对JavaBean进行生命周期和读写的管理。
IOC (Inversion of Control) Spring实现的核心是IOC,即控制反转,完全由Spring容器负责维护资源间的依赖关系。
AOP (Aspect-oriented programming)AOP框架是Spring框架中的一个子框架,以切面编程模式在不更改源代码的情况下增加新的功能。
IOC(控制反转,在程序中又称为依赖注入)
Spring 通过三种实现依赖注入:
1、接口注入
2、set注入
3、构造器注入
ApplicationContext.xml Spring 的核心配置文件
set注入
bean只需要写set 和 get 方法,不需要写构造方法。
name表示bean属性
<bean id="user" class="com.niit.User">
<property name="userName" value="tom"></property>
</bean>
如何对配置文件读取
(1)启动Spring框架,加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
(2)通过Spring容器获取管理的bean对象
User user = (User)ctx.getBean("user");
Spring 容器获取的bean对象都是相同的对象,也就是说Spring 采用的就是单例模式。
如果设置bean scope="prototype" 可以获取不同的实例
构造注入
ref 表示依赖关系
需要类带有带参构造和无参构造。
<bean id="user" class="com.niit.bean.User">
<!--构造器注入-->
<constructor-arg index ="0" value="tony"></constructor-arg>
<property name="dep" ref="dep"></property>
<bean id="dep" class="com.niit.bean.department">
<property name="depId" value="1000"></property>
<property name="depName" value="tony"></property>
</bean>
AOP 面向切面的编程
作用就是能在方法执行的前后切入相应的代码,并且不需要更改源文件本身。
代理
静态代理
动态代理
静态代理
一个代理类只能对一个bean类进行代理
IUser.java
public interface IUser {
public void details();
}
UserProxy.java
/**
* 静态代理类,该代理类只能对User类型进行代理
* @author Administrator
*
*/
public class UserProxy implements IUser {
public void details() {
System.out.println("details方法即将被调用");
user.details();
System.out.println("details方法调用完毕");
}
private IUser user;
public IUser getUser() {
return user;
}
public void setUser(IUser user) {
this.user = user;
}
}
配置applicationContext.xml
<!-- 静态代理类 -->
<bean id="userProxy" class="com.niit.proxy.UserProxy">
<property name="user" ref="user"></property>
</bean>
Test.java
IUser user = (IUser) ctx.getBean("userProxy");
user.details();
动态代理
允许对任意类进行代理
IUser.java
public interface IUser {
public void details();
}
DynaProxy.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理类,允许对任何JavaBean进行代理操作
* @author Administrator
*
*/
public class DynaProxy implements InvocationHandler {
//代理目标
private Object target;
/**
* 创建生成代理类的方法
* @return
*/
public Object createProxy(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 代理执行的方法
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(method.getName()+"将要被执行");
//执行代理目标的原方法
Object returnValue = method.invoke(target, args);
System.out.println(method.getName()+"执行完毕");
return returnValue;
}
}
配置ApplicationContext.xml
<!-- 动态代理类 -->
<bean id="dynaProxy" class="com.niit.proxy.DynaProxy"></bean>
Test.java
//动态代理
DynaProxy proxyFactory = (DynaProxy) ctx.getBean("dynaProxy");
//创建代理类
IUser user = (IUser) proxyFactory.createProxy(u);
user.details();
AOP是面向切面的编程,即在不影响程序本逻辑在基础上,以切面的方式将与业务无关的代码,如日志等信息切入至程序中,在不需要的时候也可以方便的移除。
AOP术语
切面(Aspect) 散落在多个业务对象中可被重用的和业务无关的嗲吗集合成的对象。
通知(Advice) Aspect的具体实现称为Advice,比如使用动态代理得到的代理实例就是一个Advice
连接点(JoinPoint) Aspect在切入程序中的时机称为JoinPoint,比如在方法执行前或执行后切入。
切入(PointCut) 指定哪些Aspect在哪个JoinPoint时被用在程序中。
目标(Target) Advice 被应用的对象即target,如在动态代理类代理student类,这个类就是Target。
织入(Weave) Advice应用在Target上的过程称为Weave。
Advice包含了Aspect的真正逻辑,由于Weave的JoinPoint不同,Spring提供了几种不同的Advice。
BeforeAdvice 方法使用前切入 实现MethodBeforeAdvice接口
AfterAdvice 方法执行后切入执行 实现AfterReturningAdvice接口
AroundAdvice
BeforeInterceptor.java
import java.lang.reflect.Method;
- import org.springframework.aop.MethodBeforeAdvice;
/**
* 目标方法执行前的通知
* @author Administrator
*
*/
public class BeforeInterceptor implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println(target.getClass().getName()+"类的"+method.getName()+"将要被执行");
}
- }
<!-- 配置before通知 -->
<bean id="before" class="com.niit.advice.BeforeInterceptor"></bean>
AroundInterceptor.java
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundInterceptor implements MethodInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
// TODO Auto-generated method stub
System.out.println(invocation.getMethod().getName()+"将要被执行");
//执行代理目标的方法
Object returnValue = invocation.proceed();
System.out.println(invocation.getMethod().getName()+"执行结束");
//返回代目表方法的返回值
return returnValue;
}
}
<bean id="around" class="com.niit.advice.AroundInterceptor"></bean>
自动代理配置
<!-- 配置before通知 -->
<bean id="before" class="com.niit.advice.BeforeInterceptor"></bean>
<bean id="around" class="com.niit.advice.AroundInterceptor"></bean>
<!-- 配置Spring的自动代理 -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 配置代理目标 -->
<property name="beanNames">
<list>
<value>user</value>
<value>dep</value>
</list>
</property>
<!-- 配置作用的通知(拦截器) -->
<property name="interceptorNames">
<list>
<value>around</value>
<value>before</value>
</list>
</property>
</bean>