SpringAop和AspectJ区别
1.Spring AOP是属于运行时增强,而AspectJ是编译时增强。Spring AOP基于代理(Proxying),而AspectJ基于字节码操作(Bytecode Manipulation)
2.Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单。
3.如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择AspectJ,它比SpringAOP快很多。
SpringBean的作用域有哪些
1.<B>singleton</B>:唯一bean实例,Spring中的bean默认都是单例的。
2.<B>prototype</B>:每次请求都会创建一个新的bean实例。
3.<B>request</B>:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
4.<B>session</B>:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。
5.global-session:全局session作用域,仅仅在基于Portlet的Web应用中才有意义,Spring5中已经没有了。Portlet是能够生成语义代码(例如HTML)片段的小型Java Web插件。它们基于Portlet容器,可以像Servlet一样处理HTTP请求。但是与Servlet不同,每个Portlet都有不同的会话。
SpringMVC工作原理
1.客户端(浏览器)发送请求,直接请求到DispatcherServlet。
2.DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。
3.解析到对应的Handler(也就是我们平常说的Controller控制器)。
4.HandlerAdapter会根据Handler来调用真正的处理器来处理请求和执行相对应的业务逻辑。
5.处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是逻辑上的View。
6.ViewResolver会根据逻辑View去查找实际的View。
7.DispatcherServlet把返回的Model传给View(视图渲染)。
8.把View返回给请求者(浏览器)。
Spring中用到了哪些涉及模式
1.工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。
2.代理设计模式:Spring AOP功能的实现。
3.单例设计模式:Spring中的bean默认都是单例的。
4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。
5.包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。
7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。
@Component和@Bean的区别是什么
1.作用对象不同。@Component注解作用于类,而@Bean注解作用于方法。
2.@Component注解通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用@ComponentScan注解定义要扫描的路径)。@Bean注解通常是在标有该注解的方法中定义产生这个bean,告诉Spring这是某个类的实例,当我需要用它的时候还给我。
3.@Bean注解比@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来注册bean。比如当引用第三方库的类需要装配到Spring容器的时候,就只能通过@Bean注解来实现。
Spring标记一个类为Bean的注解有哪些
我们一般使用@Autowired注解去自动装配bean。而想要把一个类标识为可以用@Autowired注解自动装配的bean,可以采用以下的注解实现:
1.<B>@Component</B>注解。通用的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪一个层,可以使用@Component注解标注。
2.<B>@Repository</B>注解。对应持久层,即Dao层,主要用于数据库相关操作。
3.<B>@Service</B>注解。对应服务层,即Service层,主要涉及一些复杂的逻辑,需要用到Dao层(注入)。
4.<B>@Controller</B>注解。对应Spring MVC的控制层,即Controller层,主要用于接受用户请求并调用Service层的方法返回数据给前端页面。
Spring管理事务的方式有几种
1.编程式事务:在代码中硬编码(不推荐使用)。
2.声明式事务:在配置文件中配置(推荐使用),分为基于XML的声明式事务和基于注解的声明式事务。
Spring的事务隔离级别有哪几种
在TransactionDefinition中定义了五个事务隔离级别
<B>ISOLATION_DEFAULT</B> 使用后端数据库默认的隔离级别,Mysql默认采用的REPEATABLE_READ隔离级别;Oracle默认采用的READ_COMMITTED隔离级别。
<B>ISOLATION_READ_UNCOMMITED</B> 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
<B>ISOLATION_READ_COMMITED</B> 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
<B>ISOLATION_REPEATABLE_READ</B> 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
<B>ISOLATION_SERIALIZABLE</B> 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
Spring事务的传播行为
在TransactionDefinition接口中定义了八个表示事务传播行为的常量
支持当前事务的情况:默认 PROPAGATION_REQUIRED
<B>PROPAGATION_REQUIRED</B> 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
<B>PROPAGATION_SUPPORTS</B> 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
<B>PROPAGATION_MANDATORY</B> 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不支持当前事务的情况:
<B>PROPAGATION_REQUEIRED_NEW</B> 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
<B>PROPAGATION_NOT_SUPPORTS</B> 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
<B>PROPAGATION_NEVER</B> 以非事务方式运行,如果当前存在事务,则抛出异常
<B>PROPAGATION_NESTED</B> 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED。
使用示例
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insert(){}
BeanFactory和FactoryBean是什么,有什么区别
1、 BeanFactory
BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是 Spring IOC 所遵守的最底层和最基本的编程规范。在 Spring 代码中, BeanFactory 只是个接口,并不是 IOC 容器的具体实现,但是 Spring 容器给出了很多种实现,如 DefaultListableBeanFactory 、 XmlBeanFactory 、 ApplicationContext 等,都是附加了某种功能的实现。
ackage org.springframework.beans.factory;
import org.springframework.beans.BeansException;
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
2、 FactoryBean
一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个 org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。
FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:
package org.springframework.beans.factory;
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
在该接口中还定义了以下3 个方法:
T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到 Spring 容器中单实例缓存池中;
boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;
Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。
当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了 getBean() 方法。
例:如果使用传统方式配置下面Cat 的 <bean> 时, Cat 的每个属性分别对应一个 <property> 元素标签。
package com.kingtao.factorybean;
public class Cat {
private int color ;
private String age ;
private double price ;
public int getColor () {
return this . color ;
}
public void setColor ( int color ) {
this . color = color;
}
public String getAge () {
return this .age ;
}
public void setBrand ( String age
this . age = age;
}
public double getPrice () {
return this . price ;
}
public void setPrice ( double price ) {
this . price = price;
}
}
如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Cat 的所有属性指定配置值:
package com.kingtao.factorybean;
import org.springframework.beans.factory.FactoryBean;
public class CatFactoryBean implements FactoryBean<Cat> {
private String catInfo ;
public Cat getObject () throws Exception {
Cat cat = new Cat () ;
String [] infos = catInfo .split ( "," ) ;
cat.setCOlor ( infos [ 0 ]) ;
cat.setAge ( Integer. valueOf ( infos [ 1 ])) ;
cat.setPrice ( Double. valueOf ( infos [ 2 ])) ;
return cat;
}
public Class<Cat> getObjectType () {
return Cat. class ;
}
public boolean isSingleton () {
return false ;
}
public String getCatInfo () {
return this . catInfo ;
}
// 接受逗号分割符设置属性信息
public void setCatInfo ( String catnfo ) {
this . catInfo = catInfo;
}
}
有了这个CatrFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Cat Bean 了:
<bean id="cat" class="com.kingtao.factorybean.CatFactoryBean"
P:catInfo="yellow ,2,2000000"/>
当调用getBean("cat") 时, Spring 通过反射机制发现 CatFactoryBean 实现了 FactoryBean 的接口,这时 Spring 容器就调用接口方法 CatFactoryBean#getObject() 方法返回。如果希望获取 CatFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&cat");
3、 区别
BeanFactory是个 Factory ,也就是 IOC 容器或对象工厂, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理的。但对 FactoryBean 而言,这个 Bean 不是简单的 Bean ,而是一个能生产或者修饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和修饰器模式类似。
网友评论