海康面试准备题

面向对象

1.面向对象的特征有哪些方面

有四大基本特征:封装、抽象、继承、多态
1、面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个体,对象状态(属性)由这个对象自己的行为(方法)来读取和改变。张三这个人,他的姓名等属性,要有自己提供的获取或改变的方法来操作。private name setName getName
2、抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。 就是把现实生活中的对象,抽象为类。
3、继承:两个类如果是父子关系,可以使用继承,子类可以复用父类所定义的内容
4、多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

2.JAVA创建对象的几种方式

1、用new语句创建对象,这是最常用的创建对象的方式。
2、运用反射手段,调用Java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
3、调用对象的clone()方法。
4、运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法.

3、重载和重写的区别

重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,跟方法返回值和访问修饰符没有关系
重写:解决子类继承父类之后,可能父类的某一个方法不满足子类的具体特征,此时需要重新在子类中定义该方法,并重写方法体.
1、重写在方法运行时,通过调用者的实际类型来确定调用的方法版本。
2、重写只发生在可见的实例方法中:私有,静态不重写。
3、重写满足一个规则:两同两小一大
1、两同:方法名和形参列表一致
2、两小:重写方法的返回值(引用类型)和抛出异常,要和被重写方法的返回值(引用类型)和抛出异常相同或者是其子类。注意,一旦返回值是基本数据类型,那么重写方法和被重写方法必须相同,且不存在自动拆装箱的问题。
3、一大:重写方法的访问修饰符大于等于被重写方法的访问修饰符。

4、讲一下String和StringBuilder的区别(final)?StringBuffer和StringBuilder的区别?

1.在java中提供三个类String StringBuillder StringBuffer来表示和操作字符串。字符串就是多个字符的集合。
String是内容不可变的字符串。String底层使用了一个不可变的字符数组(final char[])

String str =new String(“bbbb”);
每次对String类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String对象
而StringBuillder StringBuffer,是内容可以改变的字符串。StringBuillder StringBuffer底层使用的可变的字符数组(没有使用final来修饰)

2、StringBuilder是线程不安全的,效率较高.而StringBuffer是线程安全的(加了synchronized),效率较低。
3、最经典就是拼接字符串。
1、String进行拼接.String c = “a”+”b”; 常量字符串的拼接使用String,java编译器有优化
2、StringBuilder或者StringBuffer
StringBuilder sb = new StringBuilder();
sb.apend(“a”).apend(“b”)
拼接字符串不能使用String进行拼接,要使用StringBuilder或者StringBuffer

对于三者使用的总结:
1.操作少量的数据:适用String。
2.单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder。
3.多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer。

5、equal和==区别

equals只有引用数据类型有这个方法,默认继承自Object类,它的作用也是判断两个对象是否相等,但是他一般有两种使用情况:
情况1:类没有覆盖equals()方法,则是使用从父类继承的equals方法,使用==比较是否相等。
public boolean equals(Object obj) {
return (this == obj);
}
情况2:类重写了 equals()方法,一般我们都重写 equals()方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。

6、异常

在这里插入图片描述

反射

1.什么是反射

在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制

2.反射API类

1、Class类:反射的核心类,可以获取类的属性,方法等信息。
2、Field类:Java.lang.reflec包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。
3、Method类: Java.lang.reflec包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。
4、Constructor类: Java.lang.reflec包中的类,表示类的构造方法。

3.反射使用步骤(获取Class对象、调用对象方法)

1、获取想要操作的类的Class对象,他是反射的核心,通过Class对象我们可以任意调用类的方法。
2、调用Class类中的方法,既就是反射的使用阶段。
3、使用反射API来操作这些信息。

4.获取Class对象的3种方法

1、调用某个对象的getClass()方法
Person p=new Person();
Class clazz=p.getClass();
2、调用某个类的class属性来获取该类对应的Class对象
Class clazz=Person.class;
3、使用Class类中的forName()静态方法(最安全/性能最好)
Class clazz=Class.forName(“类的全路径”); (最常用)
当我们获得了想要操作的类的Class对象后,可以通过Class类中的方法获取并查看该类中的方法和属性。
每个类加载到内存后,系统都会有唯一的一份字节码对象(Person.class/Student.class字节码对象都是Class这个类的实例)

集合

在这里插入图片描述

ArrayList 底层结构是数组,底层查询快,增删慢。
LinkedList 底层结构是链表型的,增删快,查询慢。
voctor 底层结构是数组 线程安全的,增删慢,查询慢。

讲一下java中的集合?

Java中的集合分为:value,key–vale(Conllection Map)两种。
1、存储值有分为List 和Set.
List是有序的,可以重复的。
Set是无序的,不可以重复的。根据equals和hashcode判断,也就是如果
一个对象要存储在Set中,必须重写equals和hashCode方法。
2、存储key-value的为map.

.HashSet如何检查重复

当你把对象加入HashSet时,HashSet 会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的 hashcode 值作比较,如果没有相符的 hashcode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让加入操作成功。
hashCode()与 equals() 的相关规定:
1、如果两个对象相等,则 hashcode 一定也是相同的
2、两个对象相等,两个 equals() 方法返回 true
3、两个对象有相同的 hashcode 值,它们也不一定是相等的。

在这里插入图片描述

HashMap和HashSet添加重复值是替换还是覆盖

HashMap的put方法,如果key相同,值不同,则覆盖;
HashSet底层是HashMap,他的值就是HashMap的key,而value则是一个固定的Object对象。在这,相当于key相同,value也相同,故不会替换,因为这个元素已经存在。
2.9.HashMap容量
在HashMap中,有两个比较容易混淆的关键字段:size和capacity ,这其中capacity就是Map的容量,而size我们称之为Map中的元素个数。
简单打个比方你就更容易理解了:HashMap就是一个“桶”,那么容量(capacity)就是这个桶当前最多可以装多少元素,而元素个数(size)表示这个桶已经装了多少元素。

在这里插入图片描述

2.10.HashMap的树化和退化
树化规则:
当链表长度超过树化阈值 8 时,先尝试扩容来减少链表长度,如果数组容量已经 >=64,才会进行树化

退化规则
情况1:在扩容时如果拆分树时,树元素个数 <= 6 则会退化链表
情况2:
情况1:扩容 resize( ) 时,红黑树拆分成的 lo 和 hi 两颗红黑树,每一颗树的结点数小于等于临界值 6 时退化成链表。
情况2: 移除元素 remove( ) 时,在removeTreeNode( ) 方法会检查红黑树是否满足退化条件,与结点数无关。如果红黑树根 root 为空,或者 root 的左子树/右子树为空,root.left.left 根的左子树的左子树为空,都会发生红黑树退化成链表。

2.12.讲一下HashMap哈HashTable的区别?

相同点:HashMap和HasheTable都可以使用来存储key–value的数据。
区别:
1、HashMap是可以把null作为key或者value的,而HashTable是不可以的。
2、HashMap是线程不安全的,效率较高。而HashTable是线程安全的,效率较低。

2.13.HashTable和ConcurrentHashMap的区别?

我想线程安全但是我又想效率高?
Concurrent :并发
相同点:Hashtable 与 ConcurrentHashMap 都是线程安全的 Map 集合
不同点:
1、Hashtable 并发度低,整个 Hashtable 对应一把锁,同一时刻,只能有一个线程操作它
Hashtable的put方法使用的是synchronized这个锁:public synchronized V put(K key, V value)
2、ConcurrentHashMap 并发度高,整个 ConcurrentHashMap 对应多把锁,只要线程访问的是不同锁,那么不会冲突

线程、JUC并发编程

1、进程是什么?

是具有一定独立功能的程序、它是系统进行资源(内存)分配和调度的最小单位,重点在系统调度和单独的单位,也就是说进程是可以独 立运行的一段程序。

2、线程又是什么?

线程进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源。
他们之间的关系
1、一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程(通常说的主线程)。
2、资源分配给进程,同一进程的所有线程共享该进程的所有资源。
3、线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
4、CPU是分给线程,即真正在CPU上运行的是线程。
5、线程是指进程内的一个执行单元,也是进程内的可调度实体。

3、Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?

创建一个线程有4种方式:
1、继承Thread类
继承扩展性不强,java总只支持单继承,如果一个类继承Thread就不能继承其他的类了。
2、实现Runnable接口
3、实现Callable接口,重写call方法(有返回值)
4、线程池

4、什么是串行、并发、并行

串行的特点:前一个任务没搞定,下一个任务就只能等着。
concurent:并发,高并发像秒杀一样,多个线程去访问同一个资源
并行:多个事情一路并行去做,比如说我正在泡方便面,一边用热水器去烧热水,一边并行的动作拆方便面的调料包。

5、sleep() 方法和 wait() 方法区别和共同点?

共同点:两者都可以暂停线程的执行。
1、两者最主要的区别在于:sleep() 方法没有释放锁,而 wait() 方法释放了锁 。
2、wait() 通常被用于线程间交互/通信,sleep()通常被用于暂停执行。
3、wait() 方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify()或者 notifyAll() 方法。sleep()方法执行完成后,线程会自动苏醒。或者可以使用 wait(long timeout) 超时后线程会自动苏醒。

6、线程状态

在这里插入图片描述

Executors 提供四种线程池:

1)newCachedThreadPool 线程池根据需求创建线程,可扩容,遇强则强(银行一共10个窗口,只开放了3个窗口,其他7个窗口没有开放,如果人很多就要开放其余的窗口,高峰结束再回复到3个窗口状态)
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.
特点:
1、线程池中数量没有固定,可达到最大值(Interger. MAX_VALUE)
2、线程池中的线程可进行缓存重复利用和回收(回收默认时间为 1 分钟)
3、当线程池中,没有可用线程,会重新创建一个线程
场景: 适用于创建一个可无限扩大的线程池,服务器负载压力较轻,执行时间较短,任务多的场景
2)newSingleThreadExecutor 一个任务一个任务执行,一池一线程(例如窗口只能服务一个人,后面来的只能等待)
创建是一个单线程池,也就是该线程池只有一个线程在工作,所有的任务是串行执行的,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它,
此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
特点: 线程池中最多执行 1 个线程,之后提交的线程活动将会排在队列中以此执行
场景: 适用于需要保证顺序执行各个任务,并且在任意时间点,不会同时有多个线程的场景
3)newFixedThreadPool (int) 一池N线程
创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小,线程池的大小一旦达到最大值就会保持不变。
特征:
1、线程池中的线程处于一定的量,可以很好的控制线程的并发量
2、线程可以重复被使用,在显示关闭之前,都将一直存在
3、超出一定量的线程被提交时候需在队列中等待
场景: 适用于可以预测线程数量的业务中,或者服务器负载较重,对线程数有严格限制的场景
4)newScheduledThreadPool (了解)
创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。
场景: 适用于需要多个后台线程执行周期任务的场景

3.11.创建线程池的核心参数

在这里插入图片描述
都是通过new ThreadPoolExecutor来构造线程池,线程池相关参数的概念:
1)corePoolSize:3 线程池的核心线程数(常驻线程数)
线程池的核心线程数(常驻线程数),一般情况下不管有没有任务都会一直在线程池中一直存活
2)maximumPoolSize: 7 线程池所能容纳的最大线程数
线程池所能容纳的最大线程数,当活动的线程数达到这个值后,后续的新任务将会被阻塞。
3)keepAliveTime:4 线程闲置时的超时时长
控制线程闲置时的超时时长,超过则终止该线程。一般情况下用于非核心线程
4)unit: 时间单位
用于指定 keepAliveTime 参数的时间单位,TimeUnit 是个 enum 枚举类型,常用的有:TimeUnit.HOURS(小时)、TimeUnit.MINUTES(分钟)、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒)等。
5)workQueue:任务队列(阻塞队列)
当核心线程数达到最大时,新任务会放在队列中排队等待执行。
6)threadFactory:线程工厂
线程工厂,它是一个接口,用来为线程池创建新线程的。
7)RejectedExecutionHandler handler: 拒绝策略(银行有10个窗口,核心是3个窗口,所有窗口都开放,等待的座位也坐满了,银行再来新的顾客,银行没有能力接受新的顾客,银行就要做一个拒绝策略,建议去别的银行)

在这里插入图片描述

AOP和IOC的应用场景

过滤器 和 拦截器 均体现了AOP的编程思想,都可以实现诸如日志记录、登录鉴权等功能,但二者的不同点也是比较多的
1、实现原理不同
过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的。
2、使用范围不同
过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,还可以使用在其他地方
3、触发时机不同
过滤器 和 拦截器的触发时机也不同,我们看下边这张图。
在这里插入图片描述
执行顺序 :过滤前 - 拦截前 - Controller处理 - 拦截后 - 过滤后

8.6.什么是IOC和DI

控制反转(Inversion on Control)IOC:
原来在程序中手动创建对象,现在对象的创建交给外部容器来完成(这里就是交给Spring容器),这就叫控制反转。
依赖注入:Dependency injection (DI)将对象之间的相互依赖关系交给 IOC 容器来管理,并由 IOC 容器完成对象的注入。

.@Resource和@Autowired有什么区别

1、@Resource默认是按照名称装配的,要指定注入的bean的名字:@Resource(name = “studentService”)
byName 通过参数名自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。
2、@Autowired是默认按照类型装配的
byType 通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配。如果容器中有多个子类,会报错expected single matching bean but found 2: banjiServiceImpl,banjiServiceImpl2,
解决方法:
// @Resource(name = “banjiService”)
@Autowired
@Qualifier(value = “banjiServiceImpl2”)
private IBanjiService banjiService;

AOP中注解的含义

@Aspect:切面。表示一个横切进业务的一个对象。它里面包含切入点(Pointcut)和Advice(通知)。
@Pointcut:切入点。表示需要切入的位置,比如某些类或者某些方法,也就是先定一个范围。

AOP通知:
1、前置通知@Before:在方法调用之前执行
2、后置通知@AfterReturning:在方法正常调用之后执行
3、环绕通知@Around:在方法调用之前和之后,都分别可以执行的通知
4、异常通知@AfterThrowing:如果在方法调用过程中发生异常,则通知
5、最终通知 @After:在方法调用之后执行,类似于finally

@Aspect
@Component
public class ServiceLogAspect {
    public static final Logger log =
            LoggerFactory.getLogger(ServiceLogAspect.class);
    /**
     * 切面表达式:
     * execution 代表所要执行的表达式主体
     * 第一处 * 代表方法返回类型, *代表所有类型
     * 第二处 包名代表aop监控的类所在的包
     * 第三处 .. 代表该包以及其子包
     * 第四处 * 代表类名,   *代表所有类
     * 第五处 *(..) *代表类中的方法名,(..)表示方法中的任何参数
     */
    @Around("execution(* com.situ.springboot.service.impl..*.*(..))")
    public Object recordTimeLog(ProceedingJoinPoint joinPoint) throws Throwable {
        // PointCut<=JoinPoint
        // {}是占位符
        log.info("====== 开始执行 {}.{} ======",
                joinPoint.getTarget().getClass(),
                joinPoint.getSignature().getName());

        // 记录开始时间
        long begin = System.currentTimeMillis();

        // 执行目标 service
        Object result = joinPoint.proceed();

        // 记录结束时间
        long end = System.currentTimeMillis();
        long takeTime = end - begin;
        if (takeTime > 3000) {
            log.error("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
        } else if (takeTime > 2000) {
            log.warn("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
        } else {
            log.info("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
        }

        return result;
    }
}

8.10.什么是ORM?

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。可以简单的方案是采用硬编码方式(jdbc操作sql方式),为每一种可能的数据库访问操作提供单独的方法。这种方法存在很多缺陷

JVM的优化

1、堆大小设置。

Xms:初始堆大小

-Xmx:最大堆大小

-XX:NewSize=n:设置年轻代大小

-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2一个Survivor区占整个年轻代的1/5

-XX:MaxPermSize=n:设置持久代大小

2、回收器选择。

1、在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。
  2、对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数,过多的GC和Full GC是会占用很多的系统资源(主要是CPU),影响系统的吞吐量。特别要关注Full GC,因为它会对整个堆进行整理,导致Full GC一般由于以下几种情况:
一、导致Full GC一般由于以下几种情况:

1、旧生代空间不足
  调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创建过大的对象及数组避免直接在旧生代创建对象
2、Pemanet Generation空间不足
  增大Perm Gen空间,避免太多静态对象
  统计得到的GC后晋升到旧生代的平均大小大于旧生代剩余空间
  控制好新生代和旧生代的比例
3、System.gc()被显示调用
  垃圾回收不要手动触发,尽量依靠JVM自身的机制

聚集索引和非聚集索引

在 MySQL 中,B+ 树索引按照存储方式的不同分为聚集索引和非聚集索引。
1、聚集索引(聚簇索引): 聚集索引就是以主键创建的索引,在叶子节点存储的是表中的数据。
2、非聚集索引(非聚簇索引):非聚集索引就是以非主键创建的索引,在叶子节点存储的是主键和索引列。

InnoDB 存储引擎中的 B+ 树索引。

B树

B 树(Balance Tree)即为平衡树的意思,下图即是一棵 B 树:单个节点可以存储多个键值和数据的平衡树
在这里插入图片描述

B+树

在这里插入图片描述
1、B+ 树非叶子节点上是不存储数据的,仅存储键值,而 B 树节点中不仅存储键值,也会存储数据。
之所以这么做是因为在数据库中页的大小是固定的,InnoDB 中页的默认大小是 16KB。
如果不存储数据,那么就会存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖,

有一个无序集合,有几种方式进行排序

第一种称为自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则,示例如下:
实体类:(基本属性,getter/setter方法,有参无参构造方法,toString方法)

第二种叫定制排序,或自定义排序,需编写匿名内部类,先new一个Comparator接口的比较器对象c,同时实现compare()其方法;
然后将比较器对象c传给Collections.sort()方法的参数列表中,实现排序功能;

数据库关系

即一对一,一对多,多对多关系。
cart :订单
category:目录
order:订单
order_item:确认订单
product:商品列表
shipping:购物车
user:用户表

session用于权限验证

1、在Rquest.getSession()获得的session对象中存入用户权限标识、如已登录标识、角色权限标号等。

2、再次登录时通过cookie中的JSESSIONID获得session对象,如果成功获得,则查找当前对象中是否有已登录标识、无则视为未登录状态,阻止某些请求。

3、2过程中有存在登录标识的session对象再进一步根据角色权限信息判断是否继续当前请求。

MyBatis执行流程

1、读取MyBatis的配置文件。mybatis-config.xml为MyBatis的全局配置文件,用于配置数据库连接信息。
2、加载映射文件。映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在MyBatis配置文件mybatis-config.xml中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。
3、构造会话工厂。通过MyBatis的环境配置信息构建会话工厂SqlSessionFactory。
4、创建会话对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法。
5、Executor执行器。MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。
6、MappedStatement对象。在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。
7、输入参数映射。输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对preparedStatement对象设置参数的过程。
8、输出结果映射。输出结果类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输出结果映射过程类似于JDBC对结果集的解析过程。
在这里插入图片描述

springboot框架和ssm框架,优劣势对比

.spring 不说了,核心ioc、aop技术,ioc解耦,使得代码复用,可维护性大幅度提升,aop提供切面编程,同样的增强了生产力。

spring mvc是方法拦截,controller独享request response数据,采用的serlvet入口,与spring无缝对接。开发而言,spring mvc更加轻量和低入门。

mybatis嘛,看业务场景,主要是mybatis的sql可以由开发者去掌控和调优,更加直观。在业务场景比较复杂,sql好多联合关联的情况下。

SSM框架和spring boot全家桶相比有哪些优缺点?

springboot 只是为了提高开发效率,是为了提升生产力的:

1.springboot一个应用是一个可执行jar(启动类main方法启动web应用),而不像传统的war,内嵌tomcat容器,可以jar形式启动一个服务,可以快速部署发布web服务,微服务最好不过了。

2.将原有的xml配置,简化为java配置

3.当然结构可能跟一般的ssm有一定区别,但其实主要是在资源文件

SpringMVC的优点:

(1)使用简单,学习成本低。

(2)很容易就可以写出性能优秀的程序.

(3)灵活性强,Spring MVC的框架易扩展

SpringMVC的缺点:

(1)Spring与MVC 的Servlet API 耦合,难以脱离容器独立运行

(2)太过于细分,开发效率低

(3)过度追求完美,有过度设计的危险解决的问题领域是:网站应用程序或者服务开发——           URL路由、Session、模板引擎、静态Web资源等等。

优点:

对新手来说,无需任何门槛,只要懂Maven[的新手]会看文档就能亦步亦趋的开始一个新项目;

对高手来说,改配置也是分分钟的事。另外fat jar的打包方式让部署方式变得优雅。

缺点:

就是简单的背后蕴藏了巨大的学习曲线。入门容易,但是如果没有完整学习spring的体系,碰到问题就一脸懵逼。如果没有一定的经验,根本就不知道springboot自动做了什么。

注解篇

Spring中的注解主要分为两类:
类级别的注解: 如@Component、@Repository、@Controller、@Service以及JavaEE6的@ManagedBean和@Named注解,都是添加在类上面的类级别注解。

类内部的注解: 如@Bean、@Autowire、@Value、@Resource以及EJB和WebService相关的注解等,都是添加在类内部的字段或者方法上的类内部注解。

具体的来说又有以下几种类型的注解方式:
1.声明bean的注解

@Component 组件,通用的注解方式

@Service 在业务逻辑层使用(service层)

@Repository 在数据访问层使用(dao层)

@Controller 在表现层使用,控制器的声明(C)

2.注入bean的注解

@Autowired:由Spring提供

@Inject:由JSR-330提供

@Resource:由JSR-250提供

都可以注解在set方法和属性上,推荐注解在属性上(一目了然,少写代码)。

3.java配置类相关注解

@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)

@Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上)

@Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是一个bean(类上)

@ComponentScan 用于对Component进行扫描,相当于xml中的(类上)

@WishlyConfiguration 为@Configuration与@ComponentScan的组合注解,可以替代这两个注解

4.切面(AOP)相关注解

Spring支持AspectJ的注解式切面编程。

@Aspect 声明一个切面(类上)

使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。

@After 在方法执行之后执行(方法上) @Before 在方法执行之前执行(方法上) @Around 在方法执行之前与之后执行(方法上)

@PointCut 声明切点

在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持(类上)

5.@Bean的属性支持

@Scope 设置Spring容器如何新建Bean实例(方法上,得有@Bean)

其设置类型包括:

· Singleton (单例,一个Spring容器中只有一个bean实例,默认模式),

· Protetype (每次调用新建一个bean),

· Request (web项目中,给每个http request新建一个bean),

· Session (web项目中,给每个http session新建一个bean),

· GlobalSession(给每一个 global http session新建一个Bean实例)

@StepScope 在Spring Batch中还有涉及

@PostConstruct 由JSR-250提供,在构造函数执行完之后执行,等价于xml配置文件中bean的initMethod

@PreDestory 由JSR-250提供,在Bean销毁之前执行,等价于xml配置文件中bean的destroyMethod

@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值