Home / Blog / 后端
Tech · 后端

Java Spring手册

H by Haofly
· 2020-06-13 · 60 views

Spring Initializr:Spring项目初始化工具。

打包

打包成war: mvn clean package

框架分层结构

调用顺序

Controller —> Service Interface —> Service Impl —> Dao Interface —> Dao Impl —> Mapper —> DB

BIZ层

Service(业务逻辑,可以建立子文件夹来进行分类,这样每个biz就可以更细分,如果Biz和Servic都单独作为一层,那么Biz的粒度更细,Service则是提供给别人的接口)、Schedule(定时任务)、Common(一些中间件认证登录等)、Manager、RPC Service、MQTask、JobTask。也有Service和BIZ平行的分层方式,这种情况,一般是Service在调用Biz,Biz执行数据库操作,类似于Manager。

BO(Business Object)

COMMON层

一些公共的对象,公共的抽象类、公共的异常、公共的帮助方法等

DAO层

一般是由MyBatis等工具自动生成的。

DO/PO(Data Object/Persistant Object,与数据表直接对应,也叫Entity层或者Model层):用于存放实体类,与数据库中的属性值保持一致。

Mapper: 对数据库进行数据持久化操作,它的内部方法就是直接对数据库进行操作的。它类似于manager层。可以封装对数据库的复杂的操作。

VO(value object,类似于将数据库的字段抽象为新的业务相关的字段): VO往往用于请求处理层,即Controller。

INTEGRATE层

外部系统的一些接口

Web层

Controller、Config(一些初始化配置,例如线程池、缓存池等配置的初始化)

注解

@Async

  • 必须用在public方法上,同一个类的其他方法调用此方法无法实现异步
  • Spring使用的是SimpleAsyncTaskExecutor来处理@Async注解的任务
@EnableAsync
public class MyClass {
  @Async
  public void testMethod() {
    	System.out.println("Currently Executing thread name - " + Thread.currentThread().getName());
  }
}

Autowired

  • 自动注入,默认按照类型去匹配bean

@Resource

  • Autowired类似,默认按照name去匹配bean
public class Post {
  @Resource(name = "author")
  private Author author;
}

@Service用于标注业务层组件

@Controller用于标注控制层组件(如struts中的action)

@Repository用于标注数据访问组件,即DAO组件

@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

重要概念

bean

  • bean有两种初始化方法:

    • applicationContext.xml中直接添加指定的类<bean id="myBean" class="com.MyBean" init-method="initMethod"></bean>
    • 实现InitializingBean接口,并实现afterPropertiesSet方法,这样可以在所有其他的属性设置完成后才初始化该类,如果用上面的方式,则无法实现依赖注入(其他的依赖都还没有初始化)。可以在里面新建一个线程实现启动完成后添加监听线程的功能。
  • 在任意地方获取指定的bean,可以有效解决循环依赖的问题,如下,建立一个方法类:

    package com.haofly.net.common.utils;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    @Component	// 一定要加这个
    public class SpringContextUtil implements ApplicationContextAware {
        /**
         * Spring应用上下文环境
         */
        private static ApplicationContext applicationContext;
        /**
         * 实现ApplicationContextAware接口的回调方法,设置上下文环境
         */
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) {
            SpringContextUtil.applicationContext = applicationContext;
        }
    
        public static ApplicationContext getApplicationContext() {
            return applicationContext;
        }
    
        /**
         * 获取bean对象
         *
         * @param name bean名称
         * @return Object 一个以所给名字注册的bean的实例
         */
        public static Object getBean(String name) {
            return applicationContext.getBean(name);
        }
    }
    
    // 在其他地方可以这样子直接获取指定的bean
    BusniessServiceImpl businessServiceImpl = (BusinessServiceImpl) SpringContextUtil.get("businessServiceImpl");	// 需要注意的是,如果放在应用初始化的过程中,那么该类中的applicationContext可能还没有初始化,可以sleep以下或者其他方式

AOP切片

  • 切片的功能类似于中间件,或者说插件

applicationContext.xml中定义切片:

<bean id="myLogAspect" class="net.haofly.commons.util.LogAspect"></bean>
<aop:config>
  <!-- 设置切入点 -->
  <aop:pointcut expression="execution(* net.haofly.cloud.service.*.impl.*.*Impl.*(..)) and !execution(* net.haofly.service.tt.impl.ServerImpl.createServer(..))" id="myPointcut"/>	<!-- 排除某个方法直接用! -->
  
  <!-- 设置切面: 将指定bean对象中的某个方法切入到某个切入点,这里是把日志里面的validate方法切入到上面那些切入点中 -->
  <aop:aspect ref="myLogAspect">
    <aop:around method="validate" pointcut-ref="myPointcut"/>
  </aop:aspect>
</aop:config>

TroubleShooting

  • 启动时在Initializing Spring FrameworkServlet 'spring'这一句日志时候,可能是以下原因之一
    • Mybatisxml文件的id可能重复了
扩展阅读
Haofly · 豪翔天下 · 2020-06-13

评论 · Comments

评论由 Giscus 提供,需用 GitHub 账号登录;留言会同步到这个仓库的 Discussions 里。