需求:
现在有一个图书管理系统,我想统计所有服务层方法执行消耗的时间。
方法一:在每个方法中都写上统计时间的代码,不可取,如果以后又想加日志了,那岂不是还要对所有方法都写一个加日志的方法。
方法二:通过动态代理技术实现。在调用代理方法的前后分别执行统计时间的代码就行。可行。
考虑使用技术:
xml解析:dom4j
javaWeb编程:servlet+jsp+jstl表达式+开源BeanUtils+log4j2+注解
mysql数据
UML图
IOC容器类图。
登录时序图:
方法二实现:
1.第一步配置bean.xml文件。
在beans.xml中配置实体bean,然后在需要进行切面拦截的类配置aop,如下
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!-- dao层的配置 ,单例模式-->
<bean id="adminDao" class="com.cnu.library.dao.impl.AdminDaoImpl" ></bean>
<!-- 服务层的配置,单例模式 -->
<bean id="adminService" class="com.cnu.library.service.impl.AdminServiceImpl" >
<property name="adminDao" ref="adminDao"/>
</bean>
<!-- action的配置,原型模式,action不可以使用代理,因为它没有直接实现的接口 -->
<bean id="/servlet/loginAction" class="com.cnu.library.action.LoginAction" scope="prototype">
<property name="adminService" ref="adminService"/>
</bean>
<!-- 对需要进行切面处理的类进行aop配置拦截方法 -->
<aops>
<aop id="adminService" method="*" advice="com.cnu.library.advice.impl.BasicAdvice"/>
</aops>
</beans>
bean.xml文件中每个标签对应的实体类为:
1.1整个bean.xml对应的实体类为,Config
public class Config {
/**
* 存放xml配置文件中所有aop
*/
private Map<String,Aop> aops;
/**
* 存放所有bean
*/
private Map<String,Bean> beans;
1.2bean标签对应的类为Bean:
public class Bean {
//bean标签的id值
private String id;
/**
* bean描述的类
*/
private String className;
/**
* 类初始化时机,只支持单例和原型两种模式
* singleton:单例模式,容器启动就创建,默认值
* prototype:原型,每次访问都重新创建一个实例
*/
private String scope="singleton";
/**
* bean描述类的所有属性
*/
private List<Property> properties= new ArrayList<Property>();
1.3aop标签对应的类为Aop:
public class Aop {
/**
* 代理类要代理的类的id,此id的值要和被代理类的bean中id属性值一样。
*/
private String id;
/**
* 需要代理类的方法注入的通知类
*/
private String advice;
/**
* 被代理类的哪些方法需要代理执行。目前该参数的功能没有实现。
*/
private String method;
1.4property标签对应的实体类为:Property
public class Property {
/**
* 属性名
*/
private String name;
/**
* 属性值为引用对象
*/
private String ref;
/**
* 属性的值为基本类型值
*/
private String value;
2.第二步解析bean.xml文件。
将bean.xml文件解析并存放到Config中。
package com.cnu.library.config.parse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.cnu.library.config.Aop;
import com.cnu.library.config.Bean;
import com.cnu.library.config.Config;
import com.cnu.library.config.Property;
/**
*
* @author liang
*读取bean的配置文件,并返回读取结果
*/
public class ConfigManager {
/**
* 读取bean.xml配置文件,并返回包含Bean对象的Map集合
* @param path 配置文件路径
* @return Map<String,Bean>
*/
public static Config getConfig(String path) {
Config config = new Config();
//创建一个用于存放bean的Map对象
Map<String,Bean> mapBeans = new LinkedHashMap<String, Bean>();
//创建一个用于存放aop的Map对象
Map<String,Aop> mapAops = new LinkedHashMap<String, Aop>();
//构建dom4j实现
//1.创建解析器
SAXReader reader = new SAXReader();
//2.加载配置文件=document对象
Document doc = null;
try {
doc = reader.read(path);
} catch (DocumentException e) {
e.printStackTrace();