简介
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
Spring是典型的控制层的框架,Model层有Hibernate、Mybatis等框架可选,View有Struts2、Spring MVC可供选择,然而Spring处于无法被替换控制层。
AOP
Aspect Oriented Programming(面向切面编程) 是继面向对象编程后的又一伟大创造。面向切面编程可以理解为程序的运行被切成了几段,每一段都加上不同的功能,加权限,加日志等等,AOP的核心是动态代理。
AOP的术语:
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.
Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.
Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
Target(目标对象):代理的目标对象
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面): 是切入点和通知(引介)的结合
beans.xml配置文件
1
2
3
4
5
6//Spring中配置bean的基本方法(IOC构造方法实例化)
<bean id="u" class="com.spring.dao.impl.UserDaoImpl"></bean>
//将userDao注入到userService()中
<bean id="userService" class="com.spring.service.UserService">
<property name="userDao" ref="u"></property>
</bean>代理(proxy)类的实现,在method方法执行前,增加一个功能,beforeMethod()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class LogInterceptor implements InvocationHandler, org.springframework.cglib.proxy.InvocationHandler{
private Object target; //定义代理对象
public void beforeMethod(Method m){
System.out.println(m.getName()+" start"); //在被代理对象执行前,先执行该方法
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
beforeMethod(method);
method.invoke(target, args);
return null;
}
}普通Dao对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface UserDao {
public void save(User u);
public void delete();
}
public class UserDaoImpl implements UserDao{
public void save(User u) {
System.out.println("add user!");
}
public void delete() {
System.out.println("delete user!");
}
}被代理的Service类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class UserService {
private UserDao userDao;
public void add(User user){
userDao.save(user);
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class UserServiceTest {
@Test
public void testAdd(){
BeanFactory applicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
User user= new User();
user.setUserName("jessyon");
user.setPassword("12346");
userService.add(user);
}
@Test
public void testProxy(){
UserDao userDao= new UserDaoImpl();
LogInterceptor li = new LogInterceptor();
li.setTarget(userDao);
UserDao userDaoProxy=(UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), new Class[]{UserDao.class}, li);
userDaoProxy.save(new User());
userDaoProxy.delete();
}
}执行结果
1
2
3
4
5在每个方法执行前,都先执行了代理后,新增的方法
save start
add user!
delete start
delete user!注:BeanFactory和ApplicationContext的区别
- ApplicationContext类继承了BeanFactory.
- BeanFactory在使用到这个类的时候,getBean()方法的时候才会加载这个类.
- ApplicationContext类加载配置文件的时候,创建所有的类.
- ApplicationContext对BeanFactory提供了扩展:
国际化处理
事件传递
Bean自动装配
各种不同应用层的Context实现