Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。
主要由以下几个模块组成:
MVC是一种设计模式
工作原理

组件说明


Spring 框架并没有对单例 Bean 进行任何多线程的封装处理。
实际上大部分的 Spring Bean 并没有可变的状态,所以在某种程度上说 Spring 的单例 Bean 是线程安全的。如果你的 Bean 有多种状态的话,就需要自行保证线程安全。最浅显的解决办法,就是将多态 Bean 的作用域(Scope)由 Singleton 变更为 Prototype。

包目录不同
国际化
强大的事件机制(Event)
底层资源的访问
对 Web 应用的支持
延迟加载
可以看到,ApplicationContext 继承了 BeanFactory,BeanFactory 是 Spring 中比较原始的
Factory,它不支持 AOP、Web 等 Spring 插件。而 ApplicationContext 不仅包含了 BeanFactory
的所有功能,还支持 Spring 的各种插件,还以一种面向框架的方式工作以及对上下文进行分层和实现继承。
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;而 ApplicationContext 面向使用
Spring 的开发者,相比 BeanFactory 提供了更多面向实际应用的功能,几乎所有场合都可以直接使用 ApplicationContext,而不是底层的 BeanFactory。
常用容器


整个流程大致如下:
关键字:三级缓存,提前曝光。
- public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
- // 一级缓存
- private final Map
singletonObjects = new ConcurrentHashMap(256); - // 三级缓存
- private final Map
> singletonFactories = new HashMap(16); - // 二级缓存
- private final Map
earlySingletonObjects = new HashMap(16); - }
AOP(Aspect-Oriented Programming,面向切面编程)能够将那些与业务无关,却为业务模块所
共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复
代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。
Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP就会使 JDK动态代理去创建代理对象;而对于没有实现接口的对象,就无法使用JDK动态代理,转而使 CGlib动态代理生成一个被代理对象的子类来作为代理。

- public interface UserDao {
-
- void add();
-
- void update();
-
- }
-
- @Repository
- public class UserDaoImpl implements UserDao {
-
- @Autowired
- @Qualifier(value = "jdbcTemplate")
- JdbcTemplate jdbcTemplate;
-
- public JdbcTemplate getJdbcTemplate() {
- return jdbcTemplate;
- }
-
- @Override
- public void add() {
- System.out.println("do add......");
- }
-
- @Override
- public void update() {
- System.out.println("do update......");
- }
-
- }
-
- public class UserDaoProxy implements InvocationHandler {
-
- private UserDaoImpl userDaoImpl;
-
- public UserDaoProxy(UserDaoImpl userDaoImpl) {
- this.userDaoImpl = userDaoImpl;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("before do method......");
-
- method.invoke(userDaoImpl);
-
- System.out.println("after do method......");
-
- return null;
- }
-
- }
-
- /**
- * jdk动态代理
- */
- @Test
- public void testProxy() {
- Class[] clazzs = {UserDao.class};
- UserDaoProxy userDaoProxy = new UserDaoProxy(new UserDaoImpl());
- UserDao userDao = (UserDao) Proxy.newProxyInstance(TestSpring.class.getClassLoader(), clazzs, userDaoProxy);
- userDao.add();
- }
当然也可以使用AspectJ,Spring AOP中已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的 AOP 框架了。使用 AOP之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样可以大大简化代码量。我们需要增加新功能也方便,提高了系统的扩展性。日志功能、事务管理和权限管理等场景都用到了AOP。
- @Aspect
- @Component
- public class UserDaoAspect {
-
- /**
- * 相同切入点抽取
- */
- @Pointcut(value = "execution(* com.ww.spring5.dao.Impl.UserDaoImpl.add())")
- public void logPointCut() {
-
- }
-
- /**
- * 前置通知
- */
- @Before(value = "execution(* com.ww.spring5.dao.Impl.UserDaoImpl.add())")
- public void beforeAdd() {
- System.out.println("beforeAdd......");
- }
-
- /**
- * 后置通知
- */
- @After(value = "execution(* com.ww.spring5.dao.Impl.UserDaoImpl.add())")
- public void afterAdd() {
- System.out.println("afterAdd......");
- }
-
- /**
- * 环绕通知
- */
- @Around(value = "logPointCut()")
- public void aroundAdd(ProceedingJoinPoint joinPoint) throws Throwable {
- System.out.println("aroundAdd before......");
- joinPoint.proceed(); // 执行被增强的方法【UserDaoImpl.add()】
- System.out.println("aroundAdd after......");
- }
-
- /**
- * 最终通知
- */
- @AfterReturning(value = "execution(* com.ww.spring5.dao.Impl.UserDaoImpl.add())")
- public void afterReturningAdd() {
- System.out.println("afterReturningAdd......");
- }
-
- /**
- * 异常通知
- */
- @AfterThrowing(value = "execution(* com.ww.spring5.dao.Impl.UserDaoImpl.add())")
- public void afterThrowingAdd() {
- System.out.println("afterThrowingAdd......");
- }
-
- }
术语
切入点语法结构
execution([权限修饰符] [返回类型] [类全路径].[方法名称]([参数列表]))
Spring AOP是属于运行时增强,而AspectJ是编译时增强。Spring AOP基于代理(Proxying),而
AspectJ基于字节码操作(Bytecode Manipulation)。
Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。
AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单。
如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择AspectJ,它比SpringAOP快很多。
@Transactional 这个注解仅仅是一些(和事务相关的)元数据,在运行时被事务基础设施读取消
费,并使用这些元数据来配置bean的事务行为。 大致来说具有两方面功能,一是表明该方法要参
与事务,二是配置相关属性来定制事务的参与方式和运行行为。
@Transactional注解既可以标注在类上,也可以标注在方法上。当在类上时,默认应用到类里的所
有方法。如果此时方法上也标注了,则方法上的优先级高。 另外注意方法一定要是public的。
声明式事务主要是得益于Spring AOP。使用一个事务拦截器,在方法调用的前后/周围进行事务性
增强(advice),来驱动事务完成。