网站建设的战略作用,西安排名seo公司,安卓系统app开发,wordpress手机单页面不使用MVC的时候系统存在的缺陷
一个Servlet都负责了那些工作#xff1f;
负责了接收数据负责了核心的业务处理负责了数据表中的CRUD负责了页面的数据展示…
分析银行转账项目存在那些问题#xff1f;
代码的复用性太差。#xff08;代码的重用性太差#xff09; 因为没…不使用MVC的时候系统存在的缺陷
一个Servlet都负责了那些工作
负责了接收数据负责了核心的业务处理负责了数据表中的CRUD负责了页面的数据展示…
分析银行转账项目存在那些问题
代码的复用性太差。代码的重用性太差 因为没有进行“职能分工”没有独立组件的概念所以没有办法进行代码复用代码和代码之间耦合度太高扩展力太差。 耦合度太高导致了代码很难扩展。操作数据库的代码和业务混杂在一起很容易出错编写代码的时候容易出错无法专注业务逻辑的编写。
MVC架构模式
1、系统为什么要分层
希望专人干专事。各司其职。职能分工要明确。这样可以让代码耦合度降低扩展力增强组件的可复用性增强。
2、系统架构中有一个非常著名的模式MVC结构模式 MModel:业务模型层数据处理/业务处理 Dao层专门为做数据的CRUD抽取出来的一个类Dao层又叫做数据持久层。service层专门抽取处理的一个业务类只写业务在service中调用Dao层对象。在service类中有一个私有的Dao属性数据库访问对象满足has a的关系service对象通过数据库访问对象操作数据库的中表中的数据。 VView:视图/展示负责展示的组件 jsphtml… CController:控制器 在Controller中调用service对象。在Controller类中有一个service私有的属性业务对象满足has a的关系controller对象通过通过调用业务对象完成用户的业务。 在service中调用Dao。 在Controller中调用view。 C是核心是控制器是司令官。 M业务模型层处理业务处理数据的一个秘书。 V负责页面展示的一个秘书。 MVC一个司令官调度两个秘书。去做这件事。
3、Model包含什么
pojo、bean、domain封装数据用的。service抽取出来的业务处理类dao抽取出来的数据持久化层。
4、三层架构和MVC的关系
表示层/展示层/web层展示层包括控制器和view包含MVC架构模式中的V和C ControllerMVC中的控制器 一般是Servlet viewMVC中的视图层 JSPHTML… 业务逻辑层MVC中的Model中的业务处理层service service处理业务逻辑的一般是一个XxxService类名 持久化层MVC中的Model中的持久化层Dao Dao将数据持久化保存进数据库
5、持久化层中包含的技术
JDBCMyBatis…
6、SSMspring、springMVC、MyBatis
Spring项目大管家负责整个项目所都对象的创建以及维护对象和对象之间的关系。SpringMVC将MVC架构模式体现的非常完美。在这个框架的基础之上进行开发一定是用了MVC架构模式的。MyBaits持久层框架
7、展示层和业务逻辑层和持久化层的调用关系
展示层调用业务逻辑层业务逻辑层调用持久化层,
8、什么是Dao
DAO的英文全称是Data Access Object数据访问对象DAO实际上是一种设计模式属于JavaEE的设计模式之一。不是23中设计模式DAO只负责数据库表的CRUD没有任何业务逻辑在里面。没有任何业务逻辑只负责表中数据增删改查的对象有一个特殊的称谓Dao对象Dao对象是由Dao类实例化得到的。Dao类的命名规范 如果这个Dao对象专门用来处理t_user表的话Dao类可以叫做UserDao如果这个Dao对象专门用来处理t_student表的话Dao类可以叫做StudentDao 一般情况下一张表会对应一个DAO类DAO对象专门用来CRUD的对象。pojo对象POJOPlain Ordinary Java Object简单的Java对象实际就是普通JavaBeans。 以下的三个对象说的是一个东西看个人习惯都是为了封装数据的对象。 pojo对象Bean对象domain对象领域模型 使用Dao对象对数据库中的数据进行增删改查操作一般先将数据库中的数据封装成一个Java对象这样便于Java程序对数据的操作。 一般一个表对应一个JavaBean封装数据的Java对象又叫做pojo对象。 JavaBean的属性建议使用引用数据类型因为从数据库中查出来的可能返回一个null如果是基本数据类型将null赋值给基本数据类型就会抛异常尽量使用基本类型的包装类。 数据库中的一个字段对应JavaBean中的一个属性。 一条数据对应一个JavaBean对象一条记录对象一个pojo对象。有的人也会把这种专门封装数据的对象称为领域模型对象domain对象 Dao类中的方法名很固定 insertdeleteBy…updateselectBy…selectAll
9、什么是Service
service翻译为业务。是MVC架构模式中Model中的service层。service类的命名规范XxxService 学生的业务类就叫做StudentService用户的业务类就叫做UserService 业务类的方法命名规范 方法命名一定要体现出要处理的是什么业务。方法名和业务挂钩一个业务类中包含多个处理业务的方法一般一个业务对应一个方法。 在该类中编写纯业务代码。只专注业务不写别的。不和其他代码混合在一块事务一定实在Service层进行控制的。 一般是一个业务方法对应一个完整的事务。
try语句的资源自动管理机制 JDK7 特性之 try-with-resource 资源的自动管理 该try-with资源语句是try声明了一个或多个资源声明。一个资源是程序与它完成后必须关闭的对象。该try-with资源语句确保每个资源在发言结束时关闭。 代码 Test
public void test2() throws IOException {String filepath D:\\gui-config.json;try (//任何实现的java.lang.AutoCloseable对象包括实现的所有对象java.io.Closeable都可以用作资源。FileReader fileReader new FileReader(filepath);BufferedReader br new BufferedReader(fileReader)) {String curline null;while ((curline br.readLine()) ! null) {System.out.println(curline);}}
}
// FileReader 和 BufferedReader 均实现了 AutoCloseable 接口ThreadLocal源码分析 多线程访问同一个共享变量的时候容易出现并发问题特别是多个线程对一个变量进行写入的时候为了保证线程安全一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。ThreadLocal是除了加锁这种同步方式之外的一种保证多线程访问出现线程不安全的方法当我们在创建一个变量后如果每个线程对其进行访问的时候访问的都是线程自己的变量这样就不会存在线程不安全问题。 相当于一个Map集合一个线程只能对应一份数据。 一个ThreadLocal就是一个大Map集合集合的key就是当前线程对象集合的value就是我们向集合对象中存储的数据。key不用我们自己存储key是由JVM来管理的这样就可以把线程和数据关联起来。 ThreadLocal类的常用方法 T get(); // 返回当前线程对应的数据T是泛型类型就是往ThreadLocal中绑定的数据的类型
void set(T value); // 设置当前线程对应的数据绑定数据一个线程只能绑定一份数据这份数据可以是数组、集合等如果再绑定一次数据第二次绑定的数据会覆盖第一次绑定的数据。
void remove(); // 删除当前线程对应的数据不同功能的类在不同的包
三层架构层与层之间应当使用接口进行衔接。三层架构的目录规范 pojo包中存放普通JavaBean用来保存数据的Java类【这个包也可以使用domain包或者bean包替代】web包中存放控制器Controller用来调度两个秘书的司令官web目录webapp的根目录中存放view展示层的页面dao包dao包中存放以下两项内容【持久化层】 数据库访问的接口impl包中存放实现了数据库访问接口的实现类 service包中存放以下两项内容【业务处理曾】 业务处理的接口impl包中存放了实现了业务处理接口的实现类
使用了MVC架构模式之后存在的两大问题
在service层控制事务service层的事务控制代码看着有点别扭以后能不能不写可以使用动态代理机制解决这个问题。目前虽然面向接口编程了但是并没有完全解决对象和对象之间的依赖关系怎么办以后使用spring和IoC容器来解决这个问题。 对象的创建我不管了交给spring容器对象和对象之间的关系我也不管了交给spring容器
动态代理机制 什么是代理 代购中介 以中介为例中介和代理做的事情是一致的 出去打工为什么要找中介? 因为中介是专业的可选的工作种类多。也可能工厂不让个人去找工厂中介在中间起到一个担保的作用。对个人对厂商多是友好的。 …等等这些都是代理 什么是代理模式 代理模式是指为其他对象提供了一种代理以控制对这个对象的访问。在某些情况下一个对象不适合或者不能直接引用另一个对象而代理对象可以在客户类和目标对象之间起到中介的作用。换句话说是用代理对象是为了在不修改目标对象的基础上增强业务逻辑。 使用代理模式的作用 功能增强常用的作用是为了在原有的功能之上增加新的功能控制访问 实现代理的方式 静态代理 描述 代理类是自己手工实现的自己创建的一个Java类表示代理类同时你所要代理的目标类是确定的目标对象和代理对象必须同时实现同一个接口 特点 实现简单容易理解 缺点 当目标类增加了代理类可能也需要成倍的增加。代理类数量过多。当接口中功能增加了或者修改了会影响到众多的实现类那么厂家类和代理类都需要修改。影响比较多。修改的比较多出错的纪律比较大。 动态代理 优点 在静态代理目标类很多的时候可以使用动态代理避免静态代理的缺点。动态代理中目标类即使很多代理类的数量可以很少当修改了几口中的方法时不会影响代理类。 概念 在程序执行的过程中使用JDK的反射机制创建代理类对象并动态指定要代理的目标类。动态代理就是在程序运行期创建目标对象的代理对象并对目标对象中的方法进行功能性增强的一种技术在程序的执行过程中使用jdk的反射机制创建代理对象并且动态指定要代理的目标类。换句话说动态代理是一种创建java对象的能力让你不用把代理类手动写出来就能创建代理对象 动态代理的实现【动态代理分为两种】 JDK动态代理使用Java反射包中的类和接口实现动态代理的功能。 反射包java.lang.reflect里面有三个类InvocationHandler,Method,Proxy cglib动态代理cglib是第三方的工具库创建代理对象。Code Generic Library字节码生成库 cglib的原理是继承cglib通过继承目标类创建它的子类在子类中重写父类中的同名方法实现功能增强。因为cglib是继承重写方法所以要求目标类不能是final修饰的方法不能是final修饰的。cglib的要求目标类比较宽松只要能继承就可以了(而jdk动态代理还需要实现某个特定的接口)。cglib在很多的框架中使用比如spring。mybatis都有使用。 jdk动态代理的实现 反射Method类表示方法。类中的方法。通过Method可以执行某个方法 jdk动态代理的实现:反射包中有三个类InvocationHandler,Method,Proxy InvocationHandler译为调用处理程序接口就有一个方法invoke() invoke()表示代理对象要执行的功能代码你的代理类要完成的功能就写在invoke()方法中。 代理类完成的功能 调用目标代码执行目标方法的功能功能增强在目标方法调用时增加功能。 // 方法源码public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;// proxyjdk创建的代理对象。// method:目标类中的方法jdk提供method对象的代理类强转为接口当调用接口的a方法method就是a方法对象当调用接口中的b方法的时候method就是b方法对象。// args:目标类中方法的参数jdk提供的// 返回值Object对应代理类的代理方法的返回值【就是目标类返回的类型这个invoke方法的返回值也应该是什么类型的数据如果目标对象没有返回值那么invoke方法的返回值就可以随意指定了】- InvocationHandler接口表示你的代理类要干什么。- 怎么用1. 创建类实现接口InvocationHandler2. 重写Invoke()方法把原来静态代理中代理类要完成的功能写到这里来。2. Method类表示方法的确切的说就是目标类中的方法。- 作用通过Mehtod可以执行某个目标类中的方法Method.invoke();method.invoke(目标对象方法的参数)- method.invoke()是用来执行目标方法的。3. Proxy类核心对象创建代理对象。之前创建对象都是new类的构造方法现在我们使用Porxy类的方法代替new的使用。public static Object newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h) ;// loader:类加载器负责向内存中加载代理类的类加载器。【对于不同的类加载器有不同的优先级对于用户类程序员写的类的类加载器都是同一个类加载器随便取一个类加载器就可以】// interfaces:目标对象实现的接口也是反射获取的。目标对象实现了什么接口代理类就是先什么接口// h:我们自己写的代理类要完成的功能。// 返回值时Object类型的就是目标对象的代理对象代理对象肯定能强转成目标类实现的接口的类型因为目标类和代理类实现了同一个接口实现动态代理的步骤 创建接口定义目标类要完成的功能 创建目标类实现接口 创建InvocationHandler接口的实现类在invoke方法中完成代理类的功能 调用目标方法增强功能 使用Proxy类的静态方法创建代理对象并把返回值转为接口类型. 总结: 什么是动态代理机制:使用jdk动态代理机制,创建对象的能力,创建代理类的对象.而不用你创建类文件.不用写Java文件. 动态:在程序执行时,调用jdk提供的方法才能创建代理类对象.【jdk帮我们生成的代理类也实现了目标类实现的接口】jdk动态代理必须有接口,目标类必须实现接口,没有接口时,需要使用cglib动态代理 动态代理能做什么:可以在不改变原来目标方法功能的前提下,可以在代理类中增强的功能. 代理类似过滤器在执行目标方法之前执行一些增强功能的代码在目标方法之后执行一些增强功能的代码。 jdk为我们动态生成的这个代理类继承了java.lang.reflect.Proxy类实现了目标类实现的所有接口所以目标类需要实现一个接口才能使用jdk的动态代理如果没有实现接口只能使用cglib动态代理。【调用Proxy的newProxyInstance方法获取代理对象】 jdk生成的代理类头 public final class $Proxy0 extends Proxy { … } 动态代理 为目标类实现的接口中所有的方法规定了统一的增强的功能都写在invoke方法中优点代理的目标类是可以在程序的运行阶段动态调整的【所有的方法的增强功能都写在incoke方法中虽然不像静态代理那样目标类中一个方法在代理类中就有一个增强方法但是可以通过method对象判断调用的是目标类中的哪个方法从而执行不同的逻辑来完成给不同的方法定义不同的增强功能】 静态代理 为每一个方法都声明了增强的功能,确定是代理类代理的对象都是确定的缺点代理类的代码得手动写出来。【但是增强规则可以为每一个方法都写一个不同的规则】 不是只有接口才能实现动态代理只是jdk使用接口这种方式实现的动态代理机制我们不需要关心动态代理的代理类是怎么生成的我们只要会调用jdk中的方法完成动态代理的功能即可这只是一种常用的方法当然用别的方法也可以实现动态代理机制。 什么是前置通知什么是后置通知 前置通知调用目标方法之前执行的代码或者操作叫做“前置通知”后置通知调用目标方法之后执行的代码或者操作叫做“后置通知” InvocationHandler中的invoke方法的返回值应该与目标类中的目标方法的返回值一致。【InvocationHandler类中的invoke方法就相当于代理类中的代理方法在代理方法中完成目标方法的调用和功能的增强】 在一个类中想调用另一个类中的方法的时候一般都将另一个类的对象声明为私有的成员属性/或者静态属性 为什么是成员属性 以前我们写的是测试程序所以我们想调用某个类的某个方法的时候直接在main方法中调用实例化某个类的对象在调用某个类的方法。真正写业务的时候是将另一个类的对象定义为私有的成员以便于当前类的所有方法都能使用这个类中的方法。 不管调用代理对象的任何一个方法都会被方法拦截处理器拦截然后就会调用InvocationHandler类中的invoke方法。 所以输出代理对象的时候就会调用invoke方法因为输出对象的时候自动调用toString方法所以就会执行InvocationHandler中的invoke方法。 总结2 当目标类中有返回值的时候 那么InvocationHandler类中的invoke方法的返回值必须是能转换成目标类的返回值类型的对象。不然就会抛出ClassCastException。 当目标类没有返回值的时候 那么InvocationHandler类的invoke方法的返回值可以返回任意值。【这样做没有意义一般目标类返回什么值这里就返回什么值】 为什么在用sout输出代理对象的时候会调用InvocationHandler类中的invoke方法 因为jdk为我们生成的代理类toString方法底层调用了InvocationHandler类中的invoke方法。 代理类toString源码 public final String toString() {/*因为sout输出的时候会调用对象的toString方法所以在代理对象被输出的时候会调用jdk为我们生成的这个代理对象的toString方法。通过这个代理对象的源码发现底层会调用InvocationHandler类的invoke方法然后将invoke方法的返回值强转成String类型的。强转失败会抛出ClassCaseException异常。*/ toString方法首先会执行InvocationHandler的invoke方法所以return (String)super.h.invoke(this,m2,(Object[])null);
}调用接口中的任何方法都会被invoke方法拦截都会先执行invoke方法。 //假设接口中的方法是
public Student query(Long id);
//那么jdk帮我们生成的这个代理类的query方法就是这样的
public final Student query(Long var1) {/*第一个参数就是当前的代理对象jdk帮我们传入的第二个参数就是要执行的方法我们将代理对象转换成接口类型调用哪个方法m2就是哪个方法也是jdk帮我们传入的第三个参数是传入的参数,我们面向接口掉方法的时候给方法传进去的是什么样的参数第三个参数就是我们传入的这个参数。*///面向接口调用query方法的时候因为实际的对象是代理对象会调用代理对象的query方法代理对象的该方法会调用到InvocationHandler类中的invoke方法所以invoke方法会拦截接口中所有的方法// 将调用invoke方法的返回值强转成接口中定义的返回值类型如果强转不成功抛出异常所以invoke方法的返回值一般都和接口中定义的返回值一样。换句话说就是和目标类的返回值类型一致。return (Student)super.h.invoke(this,m4,new Object[]{var1});
}jdk帮我们生成的这个动态代理类的方法都是final修饰的。