小白:伟哥,我这几天自学Servlet,我想知道三层架构里,业务层和dao层的对象能不能提前创建呢?
伟哥:当然可以啦!这样就不用每次自己手动去new对象了。
那么该怎么实现呢?接下来就看伟哥带你实现一下吧。
一.Servlet三层架构
我们先来看看三层架构是怎么样的一种结构,如下图所示:
Controller层:调用对应业务层,需要持有Service层的对象;
Service层:调用对应的数据层,需要持有Dao层的对象;
约定:Service层和Dao层的每个接口只有一个实现类。
二. 相关注解
要实现相关的功能,我们可以使用如下注解。
- @Service
该注解可以添加到Service业务层的类上。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Service {
}
- @Dao
该注解可以添加到Dao层的类上。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) // 表示运行时加载
public @interface Dao {
}
三. 执行时机
要想在Servlet之前就可以加载识别到service和dao层的对象,我们可以把相关对象的创建放在Filter中的init方法中。
核心实现代码如下所示:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//全局属性:用来存储数据
ServletContext sc = filterConfig.getServletContext();
autoWireDao(sc); //解析dao
autoWireService(sc); //解析service
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
}
四.解析步骤
当上述代码被加载后,其完整的执行过程如下图所示:
最后伟哥给大家列出Dao层的代码,如下:
//自动注入dao对象
private void autoWireDao(ServletContext sc) {
//1创建dao层的相关对象
//dao层所在的包
String packageDao = "com.qfedu.dao.impl";
String packageDaoPath = packageDao.replace(".","/");
//获取真实的url路径
URL url = AutoWireFilter.class.getClassLoader().getResource(packageDaoPath);
//F:\workspace2301\property2301a\out\production\property2301a\com\qfedu\dao\impl
String filePath = url.getFile();
System.out.println("file"+ filePath );
//创建对应的文件对象
File file = new File(filePath);
//所有class文件
File[] files = file.listFiles();
for (File f1 : files) {
//文件的名称
String name = f1.getName();
if(name.endsWith(".class")) {
try {
String replace = name.replace(".class", "");
// com.qfedu.dao.impl.DevelopDaoImpl
Class<?> c = Class.forName(packageDao +"."+ replace);
//只有加了@Dao注解的类才被 实例化
if( c.isAnnotationPresent(Dao.class)) {
//key : 接口的class的名称com.qfedu.dao.IDevelopDao
String daoKey = c.getInterfaces()[0].getName();
//value
Object daoValue = c.newInstance();
System.out.println("key="+daoKey + ";"+ "value"+ daoValue);
//保存数据到 servletContext
sc.setAttribute(daoKey,daoValue);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
大家可以仿照Dao层代码,自己实现一下autoWireService(sc)方法,创建出service层的对象。现在你知道Servlet如何结合自定义注解,实现对象的创建了吗?关注千锋官方博客,干货天天都不断!
Servlet,包括Servlet最新版本的相关更多内容,如果想要了解,请扫描下方二维码,请各位多多关注!