Oracle Audit AUD$ 增长过大异常处理

某天突然发现一个 Oracle 数据库中 system 表空间大小有点异常,经过统计,原来是启用了 Oracle 的 Audit 功能,并将审计的信息存放在系统表空间。
test
数据文件大小

[[email protected] DEV]$ ll -h
total 11G
-rw-r-----. 1 oracle oinstall  9.8M Mar 28 09:56 control01.ctl
-rw-r-----. 1 oracle oinstall  101M Mar 28 09:03 example01.dbf
-rw-r-----. 1 oracle oinstall  2.0G Mar 28 09:56 oa_data01.dbf
-rw-r-----. 1 oracle oinstall  2.0G Mar 28 09:55 oa_index01.dbf
-rw-r-----. 1 oracle oinstall  2.0G Mar 28 09:21 oa_temp01.dbf
-rw-r-----. 1 oracle oinstall   51M Mar 28 08:19 redo01.log
-rw-r-----. 1 oracle oinstall   51M Mar 28 08:58 redo02.log
-rw-r-----. 1 oracle oinstall   51M Mar 28 09:56 redo03.log
-rw-r-----. 1 oracle oinstall   51M Mar 28 08:19 redo11.log
-rw-r-----. 1 oracle oinstall   51M Mar 28 08:58 redo12.log
-rw-r-----. 1 oracle oinstall   51M Mar 28 09:56 redo13.log
-rw-r-----. 1 oracle oinstall 1001M Mar 28 09:55 sysaux01.dbf
-rw-r-----. 1 oracle oinstall  5.2G Mar 28 09:56 system01.dbf
-rw-r-----. 1 oracle oinstall   30M Mar 28 05:56 temp01.dbf
-rw-r-----. 1 oracle oinstall  106M Mar 28 09:55 undotbs01.dbf
-rw-r-----. 1 oracle oinstall  5.1M Mar 28 09:03 users01.dbf

从以上输出可用看出,system01.dbf 大小为 5.2G,相比其他数据文件,有点不正常。

表空间使用统计

SELECT DS.OWNER,
       DS.SEGMENT_NAME,
       DS.SEGMENT_TYPE,
       (SUM(BYTES) / 1024 / 1024) "SEGMENT_SIZE(MB)",
       MIN(UPPER('&tablespace')) "TABLESPACE"
  FROM DBA_SEGMENTS DS
 WHERE DS.TABLESPACE_NAME = UPPER('&tablespace')
 GROUP BY DS.OWNER, DS.SEGMENT_NAME, DS.SEGMENT_TYPE
 ORDER BY SUM(BYTES) DESC;

    OWNER   SEGMENT_NAME    SEGMENT_TYPE    SEGMENT_SIZE(MB) TABLESPACE
1   SYS     AUD$            TABLE           4549             SYSTEM
2   SYS     IDL_UB1$        TABLE           240              SYSTEM
3   SYS     SOURCE$         TABLE           64               SYSTEM
4   SYS     IDL_UB2$        TABLE           30               SYSTEM
5   SYS     C_TOID_VERSION# CLUSTER         23               SYSTEM
6   SYS     C_OBJ#_INTCOL#  CLUSTER         19               SYSTEM
7   SYS     C_OBJ#          CLUSTER         12               SYSTEM
8   SYS     I_SOURCE1       INDEX           12               SYSTEM
9   SYS     ARGUMENT$       TABLE           11               SYSTEM
10  SYS     JAVA$MC$        TABLE           11               SYSTEM

其中 SYS.AUD$表占用 4549MB,大约是整个 SYSTEM 表空间的 90%。AUD$是 Oracle 数据库的审计跟踪表,专门用于存储审计跟踪信息。

异常处理

审计设置

SQL> show parameter audit

NAME                    TYPE       VALUE
---------------------- ----------- ------------------------------
audit_file_dest        string      /db/oracle/admin/DEV/adump
audit_sys_operations   boolean     FALSE
audit_syslog_level     string
audit_trail            string      DB

数据库审计是否启用通过参数AUDIT_TRAIL来设置,该参数为静态参数,要使更改生效,必须重启数据库。

在本数据库中,启用了审计,且审计的数据存储在 DB,即表SYS.AUD$中。

清除所有审计数据

SQL> conn /as sysdba
Connected.
SQL> truncate table aud$;

Table truncated.

SQL> alter table aud$ shrink;
alter table aud$ shrink
                      *
ERROR at line 1:
ORA-10630: Illegal syntax specified with SHRINK clause

The SYSTEM tablespace is created with manual segment allocation and as such it is not possible to run the SHRINK command for the objects that are located within. However, if the AUD$ table is moved to another tablespace (locally managed with automatic segment space management) then it can be shrunk.

It is recommended to use shrink on the AUD$ only during a downtime window, since part of the shrink operation will use incompatible locks.

SQL> begin
  2  dbms_audit_mgmt.set_audit_trail_location(
  3  audit_trail_type => dbms_audit_mgmt.audit_trail_db_std,
  4  audit_trail_location_value => 'USERS'
  5  );
  6  end;
  7  /

PL/SQL procedure successfully completed.

SQL> alter table aud$ enable row movement;

Table altered.

SQL> alter table sys.aud$ shrink space cascade;

Table altered.


SQL> begin
  2  dbms_audit_mgmt.set_audit_trail_location(
  3  audit_trail_type => dbms_audit_mgmt.audit_trail_db_std,
  4  audit_trail_location_value => 'SYSTEM'
  5  );
  6  end;
  7  /

PL/SQL procedure successfully completed.

查看AUD$大小

 SELECT DS.OWNER,
        DS.SEGMENT_NAME,
        DS.SEGMENT_TYPE,
        (SUM(BYTES) / 1024 / 1024) "SEGMENT_SIZE(MB)"
   FROM DBA_SEGMENTS DS
  WHERE DS.SEGMENT_NAME = UPPER('&segment')
  GROUP BY DS.OWNER, DS.SEGMENT_NAME, DS.SEGMENT_TYPE;

    OWNER   SEGMENT_NAME    SEGMENT_TYPE    SEGMENT_SIZE(MB)
1   SYS     AUD$            TABLE                     0.125

除了使用TRUNCATE,Oracle 也提供了DBMS_AUDIT_MGMT程序包,可用结合DBMS_SCHEDULE定期清理过期的审计信息。具体用法参见Auditing Enhancements in Oracle Database 11gR2

关于审计

Concepts and Overview

Database auditing is the process of recording, monitoring and reporting of the actions performed on a database. It allows the security auditors to observe whether the database users are using the database according to the established policies and that there are no policy violations. Database Auditing facilitates the analysis of the database activity patterns/trends and it can help in the process of gathering the historical data about a particular database user or activity.

One can use standard auditing to audit SQL statements, privileges, schemas, objects, and network and multitier activity. Alternatively, one can use Fine Grained Auditing (available only in Enterprise Edition) to monitor specific database activities based on factors such as actions on a database table or times when those activities occur. FGA is very flexible since the audit_condition can reference a PL/SQL function that will control whether the audit record is produced or not.

Reasons for using auditing include:

  • Enabling future accountability for current actions
  • Deterring users (or others, such as intruders) from inappropriate actions based on their accountability
  • Investigating, monitoring, and recording suspicious activity
  • Addressing auditing requirements for compliance

Auditing Installation

The database standard auditing is a feature available by default in all the database editions.

Configuration and Administration

To use auditing one must first enable it and then define exactly what must be audited. The audited actions are recorded either in the SYS.AUD$ table or in operating system files.

Enabling Auditing

The auditing is enabled by setting the AUDIT_TRAIL parameter to a value different than NONE followed by a restart of the database. The following table presents all the possible legal values for the AUDIT_TRAIL parameter:

  • NONE:Auditing is disabled
  • DB:The auditing is enabled and the audit data is written to the SYS.AUD$ table
  • DB_EXTENDED:Behaves as DB but also populates the SQL_TEXT and SQL_BIND columns
  • OS:The auditing is enabled. On Unix the audit data is written to text files which are located in the directory specified via AUDIT_FILE_DEST. On Windows the audit data will be sent to the Event Viewer.
  • XML:The auditing is enabled and the audit data is written to XML files which are located in the directory/folder specified via AUDIT_FILE_DEST. This is the case for Windows as well.
  • XML_EXTENDED:Behaves as XML but also populates the SQL_TEXT and SQL_BIND tags

As seen in the above table the location where the audit data is sent to is controlled by the AUDIT_TRAIL parameter. When this parameter is set to OS, XML or XML_EXTENDED the exact location of the audit data is controlled by AUDIT_FILE_DEST and AUDIT_SYSLOG_LEVEL. Other factors that influence the exact location for the audit data are :

  • the status of the database (started or shutdown)
  • whether the user running the audited event is a privileged user or not

The following table shows what will happen when using different combinations for these parameters/factors:

auditing_location_corr.jpg

Java Spring面试问题与解答

This post will help you get through Spring interview Questions explaining the core concepts in detail.
这篇文章将帮助你通过 Spring 面试问题 解释详细的核心概念。(zh_CN)

Spring Framework is one of the most popular Java EE framework for web applications. Dependency Injection and Aspect Oriented Programming are at the heart of Spring framework. If you are good in Spring Framework, chances of getting selected gets high.
Spring Framework 是最流行的 Web 应用程序 Java EE 框架之一。 依赖注入面向方面编程是 Spring 框架的核心。如果你擅长 Spring Framework,那么获得选择的机会就会很高。(zh_CN)

You should bookmark this post because Spring Framework is a lot bigger and chances are that I will keep on adding more questions to this list and you don’t want to miss them out.
你应该将这篇文章加入书签,因为 Spring Framework 要大得多,我可能会继续在这个列表中添加更多问题,你不想错过它们。(zh_CN)

1.What is Spring Framework?

1. 什么是 Spring Framework?(zh_CN)

Spring is one of the most widely used Java EE framework. Spring framework core concepts are “Dependency Injection” and “Aspect Oriented Programming”.
Spring 是使用最广泛的 Java EE 框架之一。 Spring 框架核心概念是“依赖注入”和“面向方面编程”。(zh_CN)

Spring framework can be used in normal java applications also to achieve loose coupling between different components by implementing dependency injection and we can perform cross cutting tasks such as logging and authentication using spring support for aspect oriented programming.
Spring 框架也可以在普通的 java 应用程序中使用,通过实现依赖注入来实现不同组件之间的松散耦合,我们可以使用 spring 支持面向方面编程来执行交叉切割任务,例如日志记录和身份验证。(zh_CN)

I like spring because it provides a lot of features and different modules for specific tasks such as Spring MVC and Spring JDBC. Since it’s an open source framework with a lot of online resources and active community members, working with Spring framework is easy and fun at same time.
我喜欢 spring,因为它为 Spring MVC 和 Spring JDBC 等特定任务提供了许多功能和不同的模块。由于它是一个包含大量在线资源和活跃社区成员的开源框架,因此使用 Spring 框架既简单又有趣。(zh_CN)

2.What are some of the important features and advantages of Spring Framework?

2.Spring Framework 的一些重要特性和优势是什么?(zh_CN)

Spring Framework is built on top of two design concepts – Dependency Injection and Aspect Oriented Programming.
Spring Framework 构建于两个设计概念之上 – 依赖注入和面向方面编程。(zh_CN)

Some of the features of spring framework are:
spring 框架的一些特性是:(zh_CN)

  • Lightweight and very little overhead of using framework for our development.
  • 使用框架进行开发的轻量级和非常小的开销。(zh_CN)
  • Dependency Injection or Inversion of Control to write components that are independent of each other, spring container takes care of wiring them together to achieve our work.
  • 依赖注入或控制反转来编写彼此独立的组件,spring 容器负责将它们连接在一起以实现我们的工作。(zh_CN)
  • Spring IoC container manages Spring Bean life cycle and project specific configurations such as JNDI lookup.
  • Spring IoC 容器管理 Spring Bean 生命周期和项目特定配置,例如 JNDI 查找。(zh_CN)
  • Spring MVC framework can be used to create web applications as well as restful web services capable of returning XML as well as JSON response.
  • Spring MVC 框架可用于创建 Web 应用程序以及能够返回 XML 和 JSON 响应的 restful Web 服务。(zh_CN)
  • Support for transaction management, JDBC operations, File uploading, Exception Handling etc with very little configurations, either by using annotations or by spring bean configuration file.
  • 通过使用注释或 spring bean 配置文件,支持事务管理,JDBC 操作,文件上载,异常处理等,配置非常少。(zh_CN)

Some of the advantages of using Spring Framework are:
使用 Spring Framework 的一些优点是:(zh_CN)

  • Reducing direct dependencies between different components of the application, usually Spring IoC container is responsible for initializing resources or beans and inject them as dependencies.
  • 减少应用程序的不同组件之间的直接依赖关系,通常 Spring IoC 容器负责初始化资源或 bean 并将它们作为依赖项注入。(zh_CN)
  • Writing unit test cases are easy in Spring framework because our business logic doesn’t have direct dependencies with actual resource implementation classes. We can easily write a test configuration and inject our mock beans for testing purposes.
  • 在 Spring 框架中编写单元测试用例很容易,因为我们的业务逻辑与实际的资源实现类没有直接的依赖关系。我们可以轻松编写测试配置并注入我们的模拟 bean 用于测试目的。(zh_CN)
  • Reduces the amount of boiler-plate code, such as initializing objects, open/close resources. I like JdbcTemplate class a lot because it helps us in removing all the boiler-plate code that comes with JDBC programming.
  • 减少重复代码的数量,例如初始化对象,打开/关闭资源。我非常喜欢 JdbcTemplate 类,因为它有助于我们删除 JDBC 编程附带的所有样板代码。(zh_CN)
  • Spring framework is divided into several modules, it helps us in keeping our application lightweight. For example, if we don’t need Spring transaction management features, we don’t need to add that dependency in our project.
  • Spring 框架分为几个模块,它有助于我们保持应用程序的轻量级。例如,如果我们不需要 Spring 事务管理功能,我们就不需要在项目中添加该依赖项。(zh_CN)
  • Spring framework support most of the Java EE features and even much more. It’s always on top of the new technologies, for example there is a Spring project for Android to help us write better code for native android applications. This makes spring framework a complete package and we don’t need to look after different framework for different requirements.
  • Spring 框架支持大多数 Java EE 功能甚至更多功能。它总是在新技术之上,例如,有一个 Android 的 Spring 项目,可以帮助我们为原生 Android 应用程序编写更好的代码。这使得 spring 框架成为一个完整的包,我们不需要为不同的需求提供不同的框架。(zh_CN)

3.

What do you understand by Dependency Injection?

你对依赖注入有什么了解?(zh_CN)

Dependency Injection design pattern allows us to remove the hard-coded dependencies and make our application loosely coupled, extendable and maintainable. We can implement dependency injection pattern to move the dependency resolution from compile-time to runtime.
依赖注入[设计模式](https://www.journaldev.com/1827/java-design-patterns-example-tutorial)允许我们删除硬编码的依赖项,并使我们的应用程序松散耦合,可扩展和可维护。我们可以实现依赖注入模式,将依赖关系解析从编译时移动到运行时。(zh_CN)

Some of the benefits of using Dependency Injection are: Separation of Concerns, Boilerplate Code reduction, Configurable components and easy unit testing.
使用依赖注入的一些好处是:关注点分离,Boilerplate 代码减少,可配置组件和简单的单元测试。(zh_CN)

Read more at Dependency Injection Tutorial. We can also use Google Guice for Dependency Injection to automate the process of dependency injection. But in most of the cases we are looking for more than just dependency injection and that’s why Spring is the top choice for this.
阅读[依赖注入教程](https://www.journaldev.com/2394/java-dependency-injection-design-pattern-example-tutorial)。我们还可以使用[Google Guice for Dependency Injection](https://www.journaldev.com/2403/google-guice-dependency-injection-example-tutorial)自动执行依赖注入过程。但在大多数情况下,我们寻求的不仅仅是依赖注入,这就是为什么Spring是最佳选择。(zh_CN)

4.

How do we implement DI in Spring Framework?

我们如何在 Spring Framework 中实现 DI?(zh_CN)

We can use Spring XML based as well as Annotation based configuration to implement DI in spring applications. For better understanding, please read Spring Dependency Injection example where you can learn both the ways with JUnit test case. The post also contains sample project zip file, that you can download and play around to learn more.
我们可以使用基于 Spring XML 和基于 Annotation 的配置来在 spring 应用程序中实现 DI。为了更好地理解,请阅读[Spring Dependency Injection](https://www.journaldev.com/2410/spring-dependency-injection)示例,其中您可以了解JUnit测试用例的两种方法。该帖子还包含示例项目zip文件,您可以下载和播放以了解更多信息。(zh_CN)

5.

What are the benefits of using Spring Tool Suite?

使用 Spring Tool Suite 有什么好处?(zh_CN)

We can install plugins into Eclipse to get all the features of Spring Tool Suite. However STS comes with Eclipse with some other important stuffs such as Maven support, Templates for creating different types of Spring projects and tc server for better performance with Spring applications.
我们可以在 Eclipse 中安装插件以获得 Spring Tool Suite 的所有功能。然而,STS 附带了 Eclipse 以及一些其他重要的东西,例如 Maven 支持,用于创建不同类型的 Spring 项目的模板和用于 Spring 应用程序的更好性能的 tc 服务器。(zh_CN)

I like STS because it highlights the Spring components and if you are using AOP pointcuts and advices, then it clearly shows which methods will come under the specific pointcut. So rather than installing everything on our own, I prefer using STS when developing Spring based applications.
我喜欢 STS,因为它突出了 Spring 组件,如果你正在使用 AOP 切入点和建议,那么它清楚地显示了特定切入点下的哪些方法。因此,我宁愿在开发基于 Spring 的应用程序时使用 STS,而不是自己安装所有内容。(zh_CN)

6.

Name some of the important Spring Modules?

列举一些重要的 Spring 模块?(zh_CN)

Some of the important Spring Framework modules are:
一些重要的 Spring Framework 模块是:(zh_CN)

  • Spring Context – for dependency injection.
  • **Spring Context ** – 用于依赖注入。(zh_CN)
  • Spring AOP – for aspect oriented programming.
  • **Spring AOP ** – 用于面向方面的编程。(zh_CN)
  • Spring DAO – for database operations using DAO pattern
  • **Spring DAO ** – 用于使用 DAO 模式的数据库操作(zh_CN)
  • Spring JDBC – for JDBC and DataSource support.
  • **Spring JDBC ** – 用于 JDBC 和 DataSource 支持。(zh_CN)
  • Spring ORM – for ORM tools support such as Hibernate
  • **Spring ORM ** – 用于 ORM 工具支持,如 Hibernate(zh_CN)
  • Spring Web Module – for creating web applications.
  • **Spring Web Module ** – 用于创建 Web 应用程序。(zh_CN)
  • Spring MVC – Model-View-Controller implementation for creating web applications, web services etc.
  • **Spring MVC ** – 用于创建 Web 应用程序,Web 服务等的 Model-View-Controller 实现。(zh_CN)

7.

What do you understand by Aspect Oriented Programming?

面向方面编程你有什么理解?(zh_CN)

Enterprise applications have some common cross-cutting concerns that is applicable for different types of Objects and application modules, such as logging, transaction management, data validation, authentication etc. In Object Oriented Programming, modularity of application is achieved by Classes whereas in AOP application modularity is achieved by Aspects and they are configured to cut across different classes methods.
企业应用程序有一些常见的横切关注点,适用于不同类型的对象和应用程序模块,如日志记录,事务管理,数据验证,身份验证等。在面向对象编程中,应用程序的模块化是通过类实现的,而在 AOP 应用程序中模块化由 Aspects 实现,它们被配置为跨越不同的类方法。(zh_CN)

AOP takes out the direct dependency of cross-cutting tasks from classes that is not possible in normal object oriented programming. For example, we can have a separate class for logging but again the classes will have to call these methods for logging the data. Read more about Spring AOP support at Spring AOP Example.
AOP 从普通面向对象编程中不可能的类中获取横切任务的直接依赖性。例如,我们可以有一个单独的日志记录类,但类再次调用这些方法来记录数据。在[Spring AOP 示例](https://www.journaldev.com/2583/spring-aop-example-tutorial-aspect-advice-pointcut-joinpoint-annotations)上阅读有关Spring AOP 支持的更多信息。(zh_CN)

8.

What is Aspect, Advice, Pointcut, JointPoint and Advice Arguments in AOP?

AOP 中的 Aspect,Advice,Pointcut,JointPoint 和 Advice Arguments 是什么?(zh_CN)

Aspect: Aspect is a class that implements cross-cutting concerns, such as transaction management. Aspects can be a normal class configured and then configured in Spring Bean configuration file or we can use Spring AspectJ support to declare a class as Aspect using @Aspect annotation.
**Aspect **:Aspect 是一个实现交叉问题的类,例如事务管理。方面可以是配置的普通类,然后在 Spring Bean 配置文件中配置,或者我们可以使用 Spring AspectJ 支持将类声明为 Aspect 使用@Aspect 注解。(zh_CN)

Advice: Advice is the action taken for a particular join point. In terms of programming, they are methods that gets executed when a specific join point with matching pointcut is reached in the application. You can think of Advices as Spring interceptors or Servlet Filters.
建议:建议是针对特定连接点采取的操作。在编程方面,它们是在应用程序中达到具有匹配切入点的特定连接点时执行的方法。您可以将建议视为[Spring interceptors](https://www.journaldev.com/2676/spring-mvc-interceptor-example-handlerinterceptor-handlerinterceptoradapter)或[Servlet Filters](https://www.journaldev.com / 1933 / java 的 servlet 的过滤器 – 例如教程)。(zh_CN)

Pointcut: Pointcut are regular expressions that is matched with join points to determine whether advice needs to be executed or not. Pointcut uses different kinds of expressions that are matched with the join points. Spring framework uses the AspectJ pointcut expression language for determining the join points where advice methods will be applied.
切入点:切入点是与连接点匹配的正则表达式,用于确定是否需要执行建议。 Pointcut 使用与连接点匹配的不同类型的表达式。 Spring 框架使用 AspectJ 切入点表达式语言来确定将应用通知方法的连接点。(zh_CN)

Join Point: A join point is the specific point in the application such as method execution, exception handling, changing object variable values etc. In Spring AOP a join points is always the execution of a method.
**Join Point **:连接点是应用程序中的特定点,例如方法执行,异常处理,更改对象变量值等。在 Spring AOP 中,连接点始终是方法的执行。(zh_CN)

Advice Arguments: We can pass arguments in the advice methods. We can use args() expression in the pointcut to be applied to any method that matches the argument pattern. If we use this, then we need to use the same name in the advice method from where argument type is determined.
建议参数:我们可以在通知方法中传递参数。我们可以在切入点中使用 args()表达式来应用于与参数模式匹配的任何方法。如果我们使用它,那么我们需要在确定参数类型的 advice 方法中使用相同的名称。(zh_CN)

These concepts seems confusing at first, but if you go through Spring Aspect, Advice Example then you can easily relate to them.
这些概念最初似乎令人困惑,但如果你经历[Spring Aspect,Advice Example](https://www.journaldev.com/2583/spring-aop-example-tutorial-aspect-advice-pointcut-joinpoint-annotations)然后你可以轻松地与他们联系。(zh_CN)

9.

What is the difference between Spring AOP and AspectJ AOP?

Spring AOP 和 AspectJ AOP 有什么区别?(zh_CN)

AspectJ is the industry-standard implementation for Aspect Oriented Programming whereas Spring implements AOP for some cases. Main differences between Spring AOP and AspectJ are:
AspectJ 是面向方面编程的行业标准实现,而 Spring 在某些情况下实现了 AOP。 Spring AOP 和 AspectJ 之间的主要区别是:(zh_CN)

  • Spring AOP is simpler to use than AspectJ because we don’t need to worry about the weaving process.
  • Spring AOP 比 AspectJ 更易于使用,因为我们不需要担心编织过程。(zh_CN)
  • Spring AOP supports AspectJ annotations, so if you are familiar with AspectJ then working with Spring AOP is easier.
  • Spring AOP 支持 AspectJ 注释,因此如果您熟悉 AspectJ,那么使用 Spring AOP 会更容易。(zh_CN)
  • Spring AOP supports only proxy-based AOP, so it can be applied only to method execution join points. AspectJ support all kinds of pointcuts.
  • Spring AOP 仅支持基于代理的 AOP,因此它只能应用于方法执行连接点。 AspectJ 支持各种切入点。(zh_CN)
  • One of the shortcoming of Spring AOP is that it can be applied only to the beans created through Spring Context.
  • Spring AOP 的一个缺点是它只能应用于通过 Spring Context 创建的 bean。(zh_CN)

10.

What is Spring IoC Container?

什么是 Spring IoC Container?(zh_CN)

Inversion of Control (IoC) is the mechanism to achieve loose-coupling between Objects dependencies. To achieve loose coupling and dynamic binding of the objects at runtime, the objects define their dependencies that are being injected by other assembler objects. Spring IoC container is the program that injects dependencies into an object and make it ready for our use.
控制反转(IoC)是实现对象依赖关系之间松散耦合的机制。为了在运行时实现对象的松耦合和动态绑定,对象定义了由其他汇编器对象注入的依赖关系。 Spring IoC 容器是将依赖项注入对象并使其可供我们使用的程序。(zh_CN)

Spring Framework IoC container classes are part of org.springframework.beans and org.springframework.context packages and provides us different ways to decouple the object dependencies.
Spring Framework IoC 容器类是其中的一部分org.springframework.beansorg.springframework.context 包并为我们提供了解耦对象依赖关系的不同方法。(zh_CN)

Some of the useful ApplicationContext implementations that we use are;
我们使用的一些有用的 ApplicationContext 实现是;(zh_CN)

  • AnnotationConfigApplicationContext: For standalone java applications using annotations based configuration.
  • AnnotationConfigApplicationContext: 对于使用基于注释的配置的独立 Java 应用程序。(zh_CN)
  • ClassPathXmlApplicationContext: For standalone java applications using XML based configuration.
  • ClassPathXmlApplicationContext: 对于使用基于 XML 的配置的独立 Java 应用程序。(zh_CN)
  • FileSystemXmlApplicationContext: Similar to ClassPathXmlApplicationContext except that the xml configuration file can be loaded from anywhere in the file system.
  • FileSystemXmlApplicationContext: 与 ClassPathXmlApplicationContext 类似,不同之处在于可以从文件系统中的任何位置加载 xml 配置文件。(zh_CN)
  • AnnotationConfigWebApplicationContext and XmlWebApplicationContext for web applications.
  • AnnotationConfigWebApplicationContextXmlWebApplicationContext 用于 Web 应用程序。(zh_CN)

11.

What is a Spring Bean?

什么是 Spring Bean?(zh_CN)

Any normal java class that is initialized by Spring IoC container is called Spring Bean. We use Spring ApplicationContext to get the Spring Bean instance.
由 Spring IoC 容器初始化的任何普通 java 类都称为 Spring Bean。我们用 SpringApplicationContext 获取 Spring Bean 实例。(zh_CN)

Spring IoC container manages the life cycle of Spring Bean, bean scopes and injecting any required dependencies in the bean.
Spring IoC 容器管理 Spring Bean 的生命周期,bean 作用域以及在 bean 中注入任何所需的依赖项。(zh_CN)

12.

What is the importance of Spring bean configuration file?

Spring bean 配置文件的重要性是什么?(zh_CN)

We use Spring Bean configuration file to define all the beans that will be initialized by Spring Context. When we create the instance of Spring ApplicationContext, it reads the spring bean xml file and initialize all of them. Once the context is initialized, we can use it to get different bean instances.
我们使用 Spring Bean 配置文件来定义将由 Spring Context 初始化的所有 bean。当我们创建 Spring ApplicationContext 的实例时,它会读取 spring bean xml 文件并初始化所有这些文件。初始化上下文后,我们可以使用它来获取不同的 bean 实例。(zh_CN)

Apart from Spring Bean configuration, this file also contains spring MVC interceptors, view resolvers and other elements to support annotations based configurations.
除了 Spring Bean 配置,该文件还包含 spring MVC 拦截器,视图解析器和其他元素,以支持基于注释的配置。(zh_CN)

13.

What are different ways to configure a class as Spring Bean?

将类配置为 Spring Bean 有哪些不同的方法?(zh_CN)

There are three different ways to configure Spring Bean.
配置 Spring Bean 有三种不同的方法。(zh_CN)

  1. XML Configuration: This is the most popular configuration and we can use bean element in context file to configure a Spring Bean. For example:
  2. XML 配置:这是最流行的配置,我们可以在上下文文件中使用 bean 元素来配置 Spring Bean。例如:(zh_CN)

    Copy

  3. Java Based Configuration: If you are using only annotations, you can configure a Spring bean using @Bean annotation. This annotation is used with @Configuration classes to configure a spring bean. Sample configuration is:

  4. 基于 Java 的配置:如果您只使用注释,则可以使用配置 Spring bean@Bean 注解。此注释用于@Configuration 用于配置 spring bean 的类。示例配置是:(zh_CN)

    Copy
    @Configuration @ComponentScan(value=”com.journaldev.spring.main”) public class MyConfiguration { @Bean public MyService getService(){ return new MyService(); } }

To get this bean from spring context, we need to use following code snippet:
要从 spring 上下文获取此 bean,我们需要使用以下代码片段:(zh_CN)

Copy
 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(       MyConfiguration.class); MyService service = ctx.getBean(MyService.class);
  1. Annotation Based Configuration: We can also use @Component, @Service, @Repository and @Controller annotations with classes to configure them to be as spring bean. For these, we would need to provide base package location to scan for these classes. For example:
  2. 基于注释的配置:我们还可以使用@Component,@ Service,@ Repository 和@Controller 注释与类来配置它们作为 spring bean。对于这些,我们需要提供基本包位置来扫描这些类。例如:(zh_CN)

    Copy

5.

What are different scopes of Spring Bean?

Spring Bean 有哪些不同的范围?(zh_CN)

There are five scopes defined for Spring Beans.
为 Spring Beans 定义了五个范围。(zh_CN)

  1. singleton: Only one instance of the bean will be created for each container. This is the default scope for the spring beans. While using this scope, make sure spring bean doesn’t have shared instance variables otherwise it might lead to data inconsistency issues because it’s not thread-safe.
  2. [singleton](https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples):只为每个容器创建一个 bean 实例。这是 spring bean 的默认范围。使用此范围时,请确保 spring bean 没有共享实例变量,否则可能会导致数据不一致问题,因为它不是线程安全的。(zh_CN)
  3. prototype: A new instance will be created every time the bean is requested.
  4. **prototype **:每次请求 bean 时都会创建一个新实例。(zh_CN)
  5. request: This is same as prototype scope, however it’s meant to be used for web applications. A new instance of the bean will be created for each HTTP request.
  6. 请求:这与原型范围相同,但它意味着用于 Web 应用程序。将为每个 HTTP 请求创建一个新的 bean 实例。(zh_CN)
  7. session: A new bean will be created for each HTTP session by the container.
  8. **session **:将为容器的每个 HTTP 会话创建一个新 bean。(zh_CN)
  9. global-session: This is used to create global session beans for Portlet applications.
  10. **global-session **:用于为 Portlet 应用程序创建全局会话 bean。(zh_CN)

Spring Framework is extendable and we can create our own scopes too, however most of the times we are good with the scopes provided by the framework.
Spring Framework 是可扩展的,我们也可以创建自己的作用域,但是大多数时候我们都很好地使用框架提供的作用域。(zh_CN)

To set spring bean scopes we can use “scope” attribute in bean element or @Scope annotation for annotation based configurations.
要设置 spring bean 范围,我们可以在 bean 元素中使用“scope”属性,或者为基于注释的配置使用@Scope 注释。(zh_CN)

15.

What is Spring Bean life cycle?

什么是 Spring Bean 生命周期?(zh_CN)

Spring Beans are initialized by Spring Container and all the dependencies are also injected. When context is destroyed, it also destroys all the initialized beans. This works well in most of the cases but sometimes we want to initialize other resources or do some validation before making our beans ready to use. Spring framework provides support for post-initialization and pre-destroy methods in spring beans.
Spring Bean 初始化 Spring Bean,并且还注入了所有依赖项。当上下文被破坏时,它也会破坏所有已初始化的 bean。这在大多数情况下运行良好,但有时我们想要初始化其他资源或在使我们的 bean 准备好使用之前进行一些验证。 Spring 框架为 spring bean 中的 post-initialization 和 pre-destroy 方法提供支持。(zh_CN)

We can do this by two ways – by implementing InitializingBean and DisposableBean interfaces or using init-method and destroy-method attribute in spring bean configurations. For more details, please read Spring Bean Life Cycle Methods.
我们可以通过两种方式实现这一目标 – 通过实施InitializingBeanDisposableBean 接口或在 spring bean 配置中使用** init-method destroy-method **属性。有关更多详细信息,请阅读[Spring Bean 生命周期方法](https://www.journaldev.com/2637/spring-bean-life-cycle)。(zh_CN)

16.

How to get ServletContext and ServletConfig object in a Spring Bean?

如何在 Spring Bean 中获取 ServletContext 和 ServletConfig 对象?(zh_CN)

There are two ways to get Container specific objects in the spring bean.
有两种方法可以在 spring bean 中获取 Container 特定对象。(zh_CN)

  1. Implementing Spring *Aware interfaces, for these ServletContextAware and ServletConfigAware interfaces, for complete example of these aware interfaces, please read Spring Aware Interfaces
  2. 为这些 ServletContextAware 和 ServletConfigAware 接口实现 Spring * Aware 接口,请参阅[Spring Aware Interfaces](https://www.journaldev.com/2637/spring-bean-life-cycle)(zh_CN)
  3. Using @Autowired annotation with bean variable of type ServletContext and ServletConfig. They will work only in servlet container specific environment only though.
  4. 运用@Autowired 带有 bean 类型变量的注释ServletContextServletConfig. 它们仅适用于 servlet 容器特定环境。(zh_CN)

    Copy
    @Autowired ServletContext servletContext;

1.

What is Bean wiring and @Autowired annotation?

什么是 Bean 接线和@Autowired 注释?(zh_CN)

The process of injection spring bean dependencies while initializing it called Spring Bean Wiring.
初始化时注入 spring bean 依赖项的过程称为 Spring Bean Wiring。(zh_CN)

Usually it’s best practice to do the explicit wiring of all the bean dependencies, but spring framework also supports autowiring. We can use @Autowired annotation with fields or methods for autowiring byType. For this annotation to work, we also need to enable annotation based configuration in spring bean configuration file. This can be done by context:annotation-config element.
通常,最佳做法是对所有 bean 依赖项进行显式连接,但 spring 框架也支持自动装配。我们可以用@Autowired 带有自动装配的字段或方法的注释。为了使这个注释起作用,我们还需要在 spring bean 配置文件中启用基于注释的配置。这可以通过** context:annotation-config **元素来完成。(zh_CN)

For more details about @Autowired annotation, please read Spring Autowire Example.
有关的更多详细信息@Autowired 注释,请阅读[Spring Autowire 示例](https://www.journaldev.com/2623/spring-autowired-annotation)。(zh_CN)

18.

What are different types of Spring Bean autowiring?

什么是不同类型的 Spring Bean 自动装配?(zh_CN)

There are four types of autowiring in Spring framework.
Spring 框架中有四种类型的自动装配。(zh_CN)

  1. autowire byName
  2. autowire byType
  3. autowire by constructor
  4. 由构造函数自动装配(zh_CN)
  5. autowiring by @Autowired and @Qualifier annotations
  6. 通过** @Autowired @ Qualifier **注释自动装配(zh_CN)

Prior to Spring 3.1, autowire by autodetect was also supported that was similar to autowire by constructor or byType. For more details about these options, please read Spring Bean Autowiring.
在 Spring 3.1 之前,还支持** autodeire by autodetect **,类似于构造函数或 byType 的 autowire。有关这些选项的更多详细信息,请阅读[Spring Bean Autowiring](https://www.journaldev.com/2623/spring-autowired-annotation)。(zh_CN)

19.

Does Spring Bean provide thread safety?

Spring Bean 是否提供线程安全性?(zh_CN)

The default scope of Spring bean is singleton, so there will be only one instance per context. That means that all the having a class level variable that any thread can update will lead to inconsistent data. Hence in default mode spring beans are not thread-safe.
Spring bean 的默认范围是 singleton,因此每个上下文只有一个实例。这意味着所有拥有任何线程可以更新的类级别变量都将导致数据不一致。因此,在默认模式下,spring bean 不是线程安全的。(zh_CN)

However we can change spring bean scope to request, prototype or session to achieve thread-safety at the cost of performance. It’s a design decision and based on the project requirements.
但是我们可以将 spring bean 范围更改为请求,原型或会话,以牺牲性能为代价来实现线程安全。这是一个设计决策,并基于项目要求。(zh_CN)

20.

What is a Controller in Spring MVC?

什么是 Spring MVC 中的 Controller?(zh_CN)

Just like MVC design pattern, Controller is the class that takes care of all the client requests and send them to the configured resources to handle it. In Spring MVC, org.springframework.web.servlet.DispatcherServlet is the front controller class that initializes the context based on the spring beans configurations.
就像 MVC 设计模式一样,Controller 是负责处理所有客户端请求并将它们发送到配置资源来处理它的类。在 Spring MVC 中,org.springframework.web.servlet.DispatcherServlet 是前端控制器类,它基于 spring bean 配置初始化上下文。(zh_CN)

A Controller class is responsible to handle different kind of client requests based on the request mappings. We can create a controller class by using @Controller annotation. Usually it’s used with @RequestMapping annotation to define handler methods for specific URI mapping.
Controller 类负责根据请求映射处理不同类型的客户端请求。我们可以使用创建一个控制器类@Controller 注解。通常它用于@RequestMapping 注释,用于定义特定 URI 映射的处理程序方法。(zh_CN)

21.

What’s the difference between @Component, @Controller, @Repository & @Service annotations in Spring?

Spring 中的@ Component,@ Controller,@ Repository 和@Service 注释有什么区别?(zh_CN)

@Component is used to indicate that a class is a component. These classes are used for auto detection and configured as bean, when annotation based configurations are used.
@组件用于指示类是组件。当使用基于注释的配置时,这些类用于自动检测并配置为 bean。(zh_CN)

@Controller is a specific type of component, used in MVC applications and mostly used with RequestMapping annotation.
**@Controller **是一种特定类型的组件,用于 MVC 应用程序,主要用于 RequestMapping 注释。(zh_CN)

@Repository annotation is used to indicate that a component is used as repository and a mechanism to store/retrieve/search data. We can apply this annotation with DAO pattern implementation classes.
@存储库注释用于指示组件用作存储库以及用于存储/检索/搜索数据的机制。我们可以将这个注释应用于 DAO 模式实现类。(zh_CN)

@Service is used to indicate that a class is a Service. Usually the business facade classes that provide some services are annotated with this.
@服务用于表示班级是服务。通常,提供某些服务的业务外观类都使用此注释。(zh_CN)

We can use any of the above annotations for a class for auto-detection but different types are provided so that you can easily distinguish the purpose of the annotated classes.
我们可以将上述任何注释用于自动检测类,但提供了不同的类型,以便您可以轻松区分注释类的用途。(zh_CN)

22.

What is DispatcherServlet and ContextLoaderListener?

什么是 DispatcherServlet 和 ContextLoaderListener?(zh_CN)

DispatcherServlet is the front controller in the Spring MVC application and it loads the spring bean configuration file and initialize all the beans that are configured. If annotations are enabled, it also scans the packages and configure any bean annotated with @Component, @Controller, @Repository or @Service annotations.
DispatcherServlet 是 Spring MVC 应用程序中的前端控制器,它加载 spring bean 配置文件并初始化所有配置的 bean。如果启用了注释,它还会扫描包并配置注释的任何 bean@Component, @Controller, @Repository 要么@Service 注释。(zh_CN)

ContextLoaderListener is the listener to start up and shut down Spring’s root WebApplicationContext. It’s important functions are to tie up the lifecycle of ApplicationContext to the lifecycle of the ServletContext and to automate the creation of ApplicationContext. We can use it to define shared beans that can be used across different spring contexts.
ContextLoaderListener 是启动和关闭 Spring 根的监听器WebApplicationContext. 它的重要功能是结束生命周期ApplicationContext 到了生命周期ServletContext 并自动创建ApplicationContext. 我们可以使用它来定义可以在不同的 spring 上下文中使用的共享 bean。(zh_CN)

23.

What is ViewResolver in Spring?

Spring 中的 ViewResolver 是什么?(zh_CN)

ViewResolver implementations are used to resolve the view pages by name. Usually we configure it in the spring bean configuration file. For example:
ViewResolver 实现用于按名称解析视图页面。通常我们在 spring bean 配置文件中配置它。例如:(zh_CN)

Copy
 <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">    <beans:property name="prefix" value="/WEB-INF/views/" />    <beans:property name="suffix" value=".jsp" /> </beans:bean>

InternalResourceViewResolver is one of the implementation of ViewResolver interface and we are providing the view pages directory and suffix location through the bean properties. So if a controller handler method returns “home”, view resolver will use view page located at /WEB-INF/views/home.jsp.
InternalResourceViewResolver 是其中一个实施ViewResolver 接口,我们通过 bean 属性提供视图页面目录和后缀位置。因此,如果控制器处理程序方法返回“home”,则视图解析程序将使用位于* / WEB-INF / views / home.jsp *的视图页面。(zh_CN)

24.

What is a MultipartResolver and when its used?

什么是 MultipartResolver 以及何时使用?(zh_CN)

MultipartResolver interface is used for uploading files – CommonsMultipartResolver and StandardServletMultipartResolver are two implementations provided by spring framework for file uploading. By default there are no multipart resolvers configured but to use them for uploading files, all we need to define a bean named “multipartResolver” with type as MultipartResolver in spring bean configurations.
MultipartResolver 界面用于上传文件 – CommonsMultipartResolverStandardServletMultipartResolver 是 spring 框架提供的两种实现文件上传。默认情况下,没有配置多部分解析器但是要使用它们来上传文件,我们需要在 spring bean 配置中定义一个名为“multipartResolver”的 bean,其类型为 MultipartResolver。(zh_CN)

Once configured, any multipart request will be resolved by the configured MultipartResolver and pass on a wrapped HttpServletRequest. Then it’s used in the controller class to get the file and process it. For a complete example, please read Spring MVC File Upload Example.
配置完成后,任何多部分请求都将由配置的 MultipartResolver 解析并传递一个包装好的 HttpServletRequest。然后在控制器类中使用它来获取文件并对其进行处理。有关完整示例,请阅读[Spring MVC 文件上载示例](https://www.journaldev.com/2573/spring-mvc-file-upload-example-single-multiple-files)。(zh_CN)

25.

How to handle exceptions in Spring MVC Framework?

如何处理 Spring MVC Framework 中的异常?(zh_CN)

Spring MVC Framework provides following ways to help us achieving robust exception handling.
Spring MVC Framework 提供了以下方法来帮助我们实现强大的异常处理。(zh_CN)

  1. Controller Based – We can define exception handler methods in our controller classes. All we need is to annotate these methods with @ExceptionHandler annotation.
  2. 基于控制器 – 我们可以在控制器类中定义异常处理程序方法。我们所需要的只是使用@ExceptionHandler 注释来注释这些方法。(zh_CN)
  3. Global Exception Handler – Exception Handling is a cross-cutting concern and Spring provides @ControllerAdvice annotation that we can use with any class to define our global exception handler.
  4. 全局异常处理程序 – 异常处理是一个跨领域的问题,Spring 提供了@ControllerAdvice 注释,我们可以使用它来定义我们的全局异常处理程序。(zh_CN)
  5. HandlerExceptionResolver implementation – For generic exceptions, most of the times we serve static pages. Spring Framework provides HandlerExceptionResolver interface that we can implement to create global exception handler. The reason behind this additional way to define global exception handler is that Spring framework also provides default implementation classes that we can define in our spring bean configuration file to get spring framework exception handling benefits.
  6. HandlerExceptionResolver 实现 – 对于一般异常,大多数时候我们提供静态页面。 Spring Framework 提供HandlerExceptionResolver 我们可以实现的接口来创建全局异常处理程序。这种额外定义全局异常处理程序的原因是 Spring 框架还提供了我们可以在 spring bean 配置文件中定义的默认实现类,以获得 spring 框架异常处理的好处。(zh_CN)

For a complete example, please read Spring Exception Handling Example.
有关完整示例,请阅读[Spring 异常处理示例](https://www.journaldev.com/2651/spring-mvc-exception-handling-controlleradvice-exceptionhandler-handlerexceptionresolver)。(zh_CN)

26.

How to create ApplicationContext in a Java Program?

如何在 Java 程序中创建 ApplicationContext?(zh_CN)

There are following ways to create spring context in a standalone java program.
有以下方法可以在独立的 Java 程序中创建 spring 上下文。(zh_CN)

  1. AnnotationConfigApplicationContext: If we are using Spring in standalone java applications and using annotations for Configuration, then we can use this to initialize the container and get the bean objects.
  2. **AnnotationConfigApplicationContext **:如果我们在独立的 Java 应用程序中使用 Spring 并使用 Configuration 的注释,那么我们可以使用它来初始化容器并获取 bean 对象。(zh_CN)
  3. ClassPathXmlApplicationContext: If we have spring bean configuration xml file in standalone application, then we can use this class to load the file and get the container object.
  4. **ClassPathXmlApplicationContext **:如果我们在独立应用程序中有 spring bean 配置 xml 文件,那么我们可以使用这个类来加载文件并获取容器对象。(zh_CN)
  5. FileSystemXmlApplicationContext: This is similar to ClassPathXmlApplicationContext except that the xml configuration file can be loaded from anywhere in the file system.
  6. **FileSystemXmlApplicationContext **:这类似于 ClassPathXmlApplicationContext,除了可以从文件系统中的任何位置加载 xml 配置文件。(zh_CN)

1.

Can we have multiple Spring configuration files?

我们可以有多个 Spring 配置文件吗?(zh_CN)

For Spring MVC applications, we can define multiple spring context configuration files through contextConfigLocation. This location string can consist of multiple locations separated by any number of commas and spaces. For example;
对于 Spring MVC 应用程序,我们可以通过定义多个 spring 上下文配置文件contextConfigLocation. 此位置字符串可以包含由任意数量的逗号和空格分隔的多个位置。例如;(zh_CN)

Copy
 <servlet>  <servlet-name>appServlet</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <init-param>             <param-name>contextConfigLocation</param-name>         <param-value>/WEB-INF/spring/appServlet/servlet-context.xml,/WEB-INF/spring/appServlet/servlet-jdbc.xml</param-value>   </init-param>   <load-on-startup>1</load-on-startup> </servlet>

We can also define multiple root level spring configurations and load it through context-param. For example;
我们还可以定义多个根级弹簧配置并通过 context-param 加载它。例如;(zh_CN)

Copy
 <context-param>    <param-name>contextConfigLocation</param-name>  <param-value>/WEB-INF/spring/root-context.xml /WEB-INF/spring/root-security.xml</param-value> </context-param>

Another option is to use import element in the context configuration file to import other configurations, for example:
另一个选项是在上下文配置文件中使用 import 元素来导入其他配置,例如:(zh_CN)

Copy
 <beans:import resource="spring-jdbc.xml"/>

28.

What is ContextLoaderListener?

什么是 ContextLoaderListener?(zh_CN)

ContextLoaderListener is the listener class used to load root context and define spring bean configurations that will be visible to all other contexts. It’s configured in web.xml file as:
ContextLoaderListener 是用于加载根上下文并定义将对所有其他上下文可见的 spring bean 配置的侦听器类。它在 web.xml 文件中配置为:(zh_CN)

Copy
 <context-param>    <param-name>contextConfigLocation</param-name>  <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param>     <listener>     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>

29.

What are the minimum configurations needed to create Spring MVC application?

创建 Spring MVC 应用程序所需的最低配置是什么?(zh_CN)

For creating a simple Spring MVC application, we would need to do following tasks.
要创建一个简单的 Spring MVC 应用程序,我们需要执行以下任务。(zh_CN)

  • Add spring-context and spring-webmvc dependencies in the project.
  • spring-contextspring-webmvc 项目中的依赖项。(zh_CN)
  • Configure DispatcherServlet in the web.xml file to handle requests through spring container.
  • 配置DispatcherServlet 在 web.xml 文件中通过 spring 容器处理请求。(zh_CN)
  • Spring bean configuration file to define beans, if using annotations then it has to be configured here. Also we need to configure view resolver for view pages.
  • 用于定义 bean 的 Spring bean 配置文件,如果使用注释,则必须在此处进行配置。我们还需要为视图页面配置视图解析器。(zh_CN)
  • Controller class with request mappings defined to handle the client requests.
  • 控制器类,其中定义了请求映射以处理客户端请求。(zh_CN)

Above steps should be enough to create a simple Spring MVC Hello World application.
上面的步骤应该足以创建一个简单的 Spring MVC Hello World 应用程序。(zh_CN)

30.

How would you relate Spring MVC Framework to MVC architecture?

您如何将 Spring MVC Framework 与 MVC 架构联系起来?(zh_CN)

As the name suggests Spring MVC is built on top of Model-View-Controller architecture. DispatcherServlet is the Front Controller in the Spring MVC application that takes care of all the incoming requests and delegate it to different controller handler methods.
顾名思义,Spring MVC 建立在** Model-View-Controller **架构之上。DispatcherServlet 是 Spring MVC 应用程序中的 Front Controller,负责处理所有传入的请求并将其委托给不同的控制器处理程序方法。(zh_CN)

Model can be any Java Bean in the Spring Framework, just like any other MVC framework Spring provides automatic binding of form data to java beans. We can set model beans as attributes to be used in the view pages.
Model 可以是 Spring Framework 中的任何 Java Bean,就像任何其他 MVC 框架一样,Spring 提供表单数据到 java bean 的自动绑定。我们可以将模型 bean 设置为要在视图页面中使用的属性。(zh_CN)

View Pages can be JSP, static HTMLs etc. and view resolvers are responsible for finding the correct view page. Once the view page is identified, control is given back to the DispatcherServlet controller. DispatcherServlet is responsible for rendering the view and returning the final response to the client.
查看页面可以是 JSP,静态 HTML 等,视图解析器负责查找正确的视图页面。一旦识别出视图页面,就会将控制权返回给 DispatcherServlet 控制器。 DispatcherServlet 负责呈现视图并将最终响应返回给客户端。(zh_CN)

31.

How to achieve localization in Spring MVC applications?

如何在 Spring MVC 应用程序中实现本地化?(zh_CN)

Spring provides excellent support for localization or i18n through resource bundles. Basis steps needed to make our application localized are:
Spring 通过资源包为本地化或 i18n 提供了出色的支持。使我们的应用程序本地化所需的基础步骤是:(zh_CN)

  1. Creating message resource bundles for different locales, such as messages_en.properties, messages_fr.properties etc.
  2. 为不同的语言环境创建消息资源包,例如 messages_en.properties,messages_fr.properties 等。(zh_CN)
  3. Defining messageSource bean in the spring bean configuration file of type ResourceBundleMessageSource or ReloadableResourceBundleMessageSource.
  4. 在类型的 spring bean 配置文件中定义 messageSource beanResourceBundleMessageSource 要么ReloadableResourceBundleMessageSource.(zh_CN)
  5. For change of locale support, define localeResolver bean of type CookieLocaleResolver and configure LocaleChangeInterceptor interceptor. Example configuration can be like below:
  6. 要更改语言环境支持,请定义 CookieLocaleResolver 类型的 localeResolver bean 并配置 LocaleChangeInterceptor 拦截器。示例配置如下所示:(zh_CN)

    Copy

  7. Use spring:message element in the view pages with key names, DispatcherServlet picks the corresponding value and renders the page in corresponding locale and return as response.

  8. 使用spring:message 在具有键名称的视图页面中,DispatcherServlet 选择相应的值并在相应的语言环境中呈现页面并作为响应返回。(zh_CN)

For a complete example, please read Spring Localization Example.
有关完整示例,请阅读[Spring Localization Example](https://www.journaldev.com/2610/spring-mvc-internationalization-i18n-and-localization-l10n-example)。(zh_CN)

32.

How can we use Spring to create Restful Web Service returning JSON response?

我们如何使用 Spring 创建 Restful Web Service 返回 JSON 响应?(zh_CN)

We can use Spring Framework to create Restful web services that returns JSON data. Spring provides integration with Jackson JSON API that we can use to send JSON response in restful web service.
我们可以使用 Spring Framework 创建返回 JSON 数据的 Restful Web 服务。 Spring 提供了与[Jackson JSON](https://www.journaldev.com/2324/jackson-json-java-parser-api-example-tutorial)API的集成,我们可以使用它在宁静的Web服务中发送JSON响应。(zh_CN)

We would need to do following steps to configure our Spring MVC application to send JSON response:
我们需要执行以下步骤来配置 Spring MVC 应用程序以发送 JSON 响应:(zh_CN)

  1. Adding Jackson JSON dependencies, if you are using Maven it can be done with following code:
  2. 添加[Jackson](https://www.journaldev.com/2324/jackson-json-java-parser-api-example-tutorial)JSON依赖项,如果您使用的是Maven,可以使用以下代码完成:(zh_CN)

    Copy

    com.fasterxml.jackson.core jackson-databind ${jackson.databind-version}

  3. Configure RequestMappingHandlerAdapter bean in the spring bean configuration file and set the messageConverters property to MappingJackson2HttpMessageConverter bean. Sample configuration will be:

  4. 配置RequestMappingHandlerAdapter bean 在 spring bean 配置文件中并将 messageConverters 属性设置为 MappingJackson2HttpMessageConverter bean。示例配置将是:(zh_CN)

    Copy

  5. In the controller handler methods, return the Object as response using @ResponseBody annotation. Sample code:

  6. 在控制器处理程序方法中,使用返回 Object 作为响应@ResponseBody 注解。示例代码:(zh_CN)

    Copy
    @RequestMapping(value = EmpRestURIConstants.GET_EMP, method = RequestMethod.GET) public @ResponseBody Employee getEmployee(@PathVariable(“id”) int empId) { logger.info(“Start getEmployee. ID=”+empId); return empData.get(empId); }

  7. You can invoke the rest service through any API, but if you want to use Spring then we can easily do it using RestTemplate class.

  8. 您可以通过任何 API 调用其余服务,但是如果您想使用 Spring,那么我们可以使用 RestTemplate 类轻松地完成它。(zh_CN)

For a complete example, please read Spring Restful Webservice Example.
有关完整示例,请阅读[Spring Restful Webservice 示例](https://www.journaldev.com/2552/spring-rest-example-tutorial-spring-restful-web-services)。(zh_CN)

33.

What are some of the important Spring annotations you have used?

您使用过的一些重要的 Spring 注释是什么?(zh_CN)

Some of the Spring annotations that I have used in my project are:
我在项目中使用的一些 Spring 注释是:(zh_CN)

  • @Controller – for controller classes in Spring MVC project.
  • @控制器 – 用于 Spring MVC 项目中的控制器类。(zh_CN)
  • @RequestMapping – for configuring URI mapping in controller handler methods. This is a very important annotation, so you should go through Spring MVC RequestMapping Annotation Examples
  • **@RequestMapping ** – 用于在控制器处理程序方法中配置 URI 映射。这是一个非常重要的注释,所以你应该通过[Spring MVC RequestMapping Annotation examples](https://www.journaldev.com/3358/spring-requestmapping-requestparam-pathvariable-example)(zh_CN)
  • @ResponseBody – for sending Object as response, usually for sending XML or JSON data as response.
  • **@ResponseBody ** – 用于发送 Object 作为响应,通常用于发送 XML 或 JSON 数据作为响应。(zh_CN)
  • @PathVariable – for mapping dynamic values from the URI to handler method arguments.
  • **@PathVariable ** – 用于将动态值从 URI 映射到处理程序方法参数。(zh_CN)
  • @Autowired – for autowiring dependencies in spring beans.
  • @自动装配 – 用于在 spring bean 中自动连接依赖项。(zh_CN)
  • @Qualifier – with @Autowired annotation to avoid confusion when multiple instances of bean type is present.
  • @限定符 – 使用@Autowired 注释以避免在存在多个 bean 类型实例时出现混淆。(zh_CN)
  • @Service – for service classes.
  • @服务 – 用于服务类。(zh_CN)
  • @Scope – for configuring scope of the spring bean.
  • @范围 – 用于配置 spring bean 的范围。(zh_CN)
  • @Configuration, @ComponentScan and @Bean – for java based configurations.
  • @配置,** @ ComponentScan @ Bean ** – 用于基于 java 的配置。(zh_CN)
  • AspectJ annotations for configuring aspects and advices, @Aspect, @Before, @After, @Around, @Pointcut etc.
  • 用于配置方面和建议的 AspectJ 注释,** @ Aspect @ Before @ After @ Around @ Pointcut **等(zh_CN)

34.

Can we send an Object as the response of Controller handler method?

我们可以发送一个 Object 作为 Controller 处理程序方法的响应吗?(zh_CN)

Yes we can, using @ResponseBody annotation. This is how we send JSON or XML based response in restful web services.
是的,我们可以使用** @ ResponseBody **注释。这就是我们在 restful Web 服务中发送基于 JSON 或 XML 的响应的方式。(zh_CN)

35.

How to upload file in Spring MVC Application?

如何在 Spring MVC Application 中上传文件?(zh_CN)

Spring provides built-in support for uploading files through MultipartResolver interface implementations. It’s very easy to use and requires only configuration changes to get it working. Obviously we would need to write controller handler method to handle the incoming file and process it. For a complete example, please refer Spring File Upload Example.
Spring 通过** MultipartResolver **接口实现为上传文件提供内置支持。它非常易于使用,只需要更改配置即可使其正常工作。显然,我们需要编写控制器处理程序方法来处理传入的文件并对其进行处理。有关完整示例,请参阅[Spring File Upload Example](https://www.journaldev.com/2573/spring-mvc-file-upload-example-single-multiple-files)。(zh_CN)

36.

How to validate form data in Spring Web MVC Framework?

如何在 Spring Web MVC Framework 中验证表单数据?(zh_CN)

Spring supports JSR-303 annotation based validations as well as provide Validator interface that we can implement to create our own custom validator. For using JSR-303 based validation, we need to annotate bean variables with the required validations.
Spring 支持基于 JSR-303 注释的验证,并提供我们可以实现的 Validator 接口来创建我们自己的自定义验证器。对于使用基于 JSR-303 的验证,我们需要使用所需的验证来注释 bean 变量。(zh_CN)

For custom validator implementation, we need to configure it in the controller class. For a complete example, please read Spring MVC Form Validation Example.
对于自定义验证器实现,我们需要在控制器类中进行配置。有关完整示例,请阅读[Spring MVC 表单验证示例](https://www.journaldev.com/2668/spring-validation-example-mvc-validator)。(zh_CN)

37.

What is Spring MVC Interceptor and how to use it?

什么是 Spring MVC Interceptor 以及如何使用它?(zh_CN)

Spring MVC Interceptors are like Servlet Filters and allow us to intercept client request and process it. We can intercept client request at three places – preHandle, postHandle and afterCompletion.
Spring MVC 拦截器就像 Servlet 过滤器,允许我们拦截客户端请求并对其进行处理。我们可以在三个地方拦截客户请求 – ** preHandle postHandle afterCompletion **。(zh_CN)

We can create spring interceptor by implementing HandlerInterceptor interface or by extending abstract class HandlerInterceptorAdapter.
我们可以通过实现 HandlerInterceptor 接口或扩展抽象类** HandlerInterceptorAdapter **来创建 spring 拦截器。(zh_CN)

We need to configure interceptors in the spring bean configuration file. We can define an interceptor to intercept all the client requests or we can configure it for specific URI mapping too. For a detailed example, please refer Spring MVC Interceptor Example.
我们需要在 spring bean 配置文件中配置拦截器。我们可以定义拦截器来拦截所有客户端请求,或者我们也可以为特定的 URI 映射配置拦截器。有关详细示例,请参阅[Spring MVC Interceptor 示例](https://www.journaldev.com/2676/spring-mvc-interceptor-example-handlerinterceptor-handlerinterceptoradapter)。(zh_CN)

38.

What is Spring JdbcTemplate class and how to use it?

什么是 Spring JdbcTemplate 类以及如何使用它?(zh_CN)

Spring Framework provides excellent integration with JDBC API and provides JdbcTemplate utility class that we can use to avoid bolier-plate code from our database operations logic such as Opening/Closing Connection, ResultSet, PreparedStatement etc.
Spring Framework 提供了与 JDBC API 的出色集成,并提供了 JdbcTemplate 实用程序类,我们可以使用它来避免来自我们的数据库操作逻辑的 bolier-plate 代码,例如 Opening / Closing Connection,ResultSet,PreparedStatement 等。(zh_CN)

For JdbcTemplate example, please refer Spring JDBC Example.
有关 JdbcTemplate 示例,请参阅[Spring JDBC 示例](https://www.journaldev.com/2593/spring-jdbc-example)。(zh_CN)

39.

How to use Tomcat JNDI DataSource in Spring Web Application?

如何在 Spring Web 应用程序中使用 Tomcat JNDI DataSource?(zh_CN)

For using servlet container configured JNDI DataSource, we need to configure it in the spring bean configuration file and then inject it to spring beans as dependencies. Then we can use it with JdbcTemplate to perform database operations.
为了使用 servlet 容器配置的 JNDI DataSource,我们需要在 spring bean 配置文件中配置它,然后将它作为依赖项注入 spring bean。然后我们可以用它JdbcTemplate 执行数据库操作。(zh_CN)

Sample configuration would be:
示例配置为:(zh_CN)

Copy
 <beans:bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">     <beans:property name="jndiName" value="java:comp/env/jdbc/MyLocalDB"/> </beans:bean>

For complete example, please refer Spring Tomcat JNDI Example.
有关完整示例,请参阅[Spring Tomcat JNDI 示例](https://www.journaldev.com/2597/spring-datasource-jndi-with-tomcat-example)。(zh_CN)

40.

How would you achieve Transaction Management in Spring?

您如何在 Spring 中实现事务管理?(zh_CN)

Spring framework provides transaction management support through Declarative Transaction Management as well as programmatic transaction management. Declarative transaction management is most widely used because it’s easy to use and works in most of the cases.
Spring 框架通过声明式事务管理以及程序化事务管理提供事务管理支持。声明式事务管理是最广泛使用的,因为它易于使用并且在大多数情况下都有效。(zh_CN)

We use annotate a method with @Transactional annotation for Declarative transaction management. We need to configure transaction manager for the DataSource in the spring bean configuration file.
我们使用注释方法@Transactional 声明式事务管理的注释。我们需要在 spring bean 配置文件中为 DataSource 配置事务管理器。(zh_CN)

Copy
 <bean id="transactionManager"     class="org.springframework.jdbc.datasource.DataSourceTransactionManager">     <property name="dataSource" ref="dataSource" /> </bean>

41.

What is Spring DAO?

什么是春天 DAO?(zh_CN)

Spring DAO support is provided to work with data access technologies like JDBC, Hibernate in a consistent and easy way. For example we have JdbcDaoSupport, HibernateDaoSupport, JdoDaoSupport and JpaDaoSupport for respective technologies.
提供 Spring DAO 支持以一致且简单的方式使用 JDBC,Hibernate 等数据访问技术。例如,我们有JdbcDaoSupport, HibernateDaoSupport, JdoDaoSupportJpaDaoSupport 各种技术。(zh_CN)

Spring DAO also provides consistency in exception hierarchy and we don’t need to catch specific exceptions.
Spring DAO 还提供异常层次结构的一致性,我们不需要捕获特定的异常。(zh_CN)

42.

How to integrate Spring and Hibernate Frameworks?

如何集成 Spring 和 Hibernate 框架?(zh_CN)

We can use Spring ORM module to integrate Spring and Hibernate frameworks, if you are using Hibernate 3+ where SessionFactory provides current session, then you should avoid using HibernateTemplate or HibernateDaoSupport classes and better to use DAO pattern with dependency injection for the integration.
我们可以使用 Spring ORM 模块来集成 Spring 和 Hibernate 框架,如果你使用 Hibernate 3+,其中 SessionFactory 提供当前会话,那么你应该避免使用HibernateTemplate 要么HibernateDaoSupport 类和更好地使用 DAO 模式和依赖注入进行集成。(zh_CN)

Also Spring ORM provides support for using Spring declarative transaction management, so you should utilize that rather than going for hibernate boiler-plate code for transaction management.
此外,Spring ORM 还支持使用 Spring 声明式事务管理,因此您应该使用它而不是使用 hibernate 样板代码进行事务管理。(zh_CN)

For better understanding you should go through following tutorials:
为了更好地理解,您应该阅读以下教程:(zh_CN)

43.

What is Spring Security?

什么是 Spring Security?(zh_CN)

Spring security framework focuses on providing both authentication and authorization in java applications. It also takes care of most of the common security vulnerabilities such as CSRF attack.
Spring 安全框架侧重于在 Java 应用程序中提供身份验证和授权。它还会处理大多数常见的安全漏洞,例如 CSRF 攻击。(zh_CN)

It’s very beneficial and easy to use Spring security in web applications, through the use of annotations such as @EnableWebSecurity. You should go through following posts to learn how to use Spring Security framework.
通过使用诸如的注释,在 Web 应用程序中使用 Spring 安全性非常有用且易于使用@EnableWebSecurity. 您应该通过以下帖子来了解如何使用 Spring Security 框架。(zh_CN)

44.

How to inject a java.util.Properties into a Spring Bean?

如何将 java.util.Properties 注入 Spring Bean?(zh_CN)

We need to define propertyConfigurer bean that will load the properties from the given property file. Then we can use Spring EL support to inject properties into other bean dependencies. For example;
我们需要定义 propertyConfigurer bean,它将从给定的属性文件加载属性。然后我们可以使用 Spring EL 支持将属性注入其他 bean 依赖项。例如;(zh_CN)

Copy
 <bean id="propertyConfigurer"    class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">     <property name="location" value="/WEB-INF/application.properties" /> </bean>   <bean class="com.journaldev.spring.EmployeeDaoImpl">     <property name="maxReadResults" value="${results.read.max}"/> </bean>

If you are using annotation to configure the spring bean, then you can inject property like below.
如果您使用注释来配置 spring bean,那么您可以注入如下所示的属性。(zh_CN)

Copy
 @Value("${maxReadResults}")  private int maxReadResults;

45.

Name some of the design patterns used in Spring Framework?

列举 Spring Framework 中使用的一些设计模式?(zh_CN)

Spring Framework is using a lot of design patterns, some of the common ones are:
Spring Framework 使用了很多设计模式,其中一些常见的是:(zh_CN)

  1. Singleton Pattern: Creating beans with default scope.
  2. 单例模式:创建具有默认范围的 bean。(zh_CN)
  3. Factory Pattern: Bean Factory classes
  4. [工厂模式](https://www.journaldev.com/1392/factory-design-pattern-in-java):Bean工厂类(zh_CN)
  5. Prototype Pattern: Bean scopes
  6. [原型模式](https://www.journaldev.com/1440/prototype-design-pattern-in-java):Bean范围(zh_CN)
  7. Adapter Pattern: Spring Web and Spring MVC
  8. [适配器模式](https://www.journaldev.com/1487/adapter-design-pattern-java):Spring Web 和 Spring MVC(zh_CN)
  9. Proxy Pattern: Spring Aspect Oriented Programming support
  10. [代理模式](https://www.journaldev.com/1572/proxy-design-pattern):Spring面向方面编程支持(zh_CN)
  11. Template Method Pattern: JdbcTemplate, HibernateTemplate etc
  12. [模板方法模式](https://www.journaldev.com/1763/template-method-design-pattern-in-java):JdbcTemplate,HibernateTemplate等(zh_CN)
  13. Front Controller: Spring MVC DispatcherServlet
  14. Data Access Object: Spring DAO support
  15. 数据访问对象:Spring DAO 支持(zh_CN)
  16. Dependency Injection and Aspect Oriented Programming
  17. 依赖注入和面向方面编程(zh_CN)

1.

What are some of the best practices for Spring Framework?

Spring Framework 有哪些最佳实践?(zh_CN)

Some of the best practices for Spring Framework are:
Spring Framework 的一些最佳实践是:(zh_CN)

  1. Avoid version numbers in schema reference, to make sure we have the latest configs.
  2. 避免模 ​​ 式参考中的版本号,以确保我们有最新的配置。(zh_CN)
  3. Divide spring bean configurations based on their concerns such as spring-jdbc.xml, spring-security.xml.
  4. 根据 spring-jdbc.xml,spring-security.xml 等问题划分 spring bean 配置。(zh_CN)
  5. For spring beans that are used in multiple contexts in Spring MVC, create them in the root context and initialize with listener.
  6. 对于在 Spring MVC 中的多个上下文中使用的 spring bean,在根上下文中创建它们并使用 listener 初始化。(zh_CN)
  7. Configure bean dependencies as much as possible, try to avoid autowiring as much as possible.
  8. 尽可能配置 bean 依赖关系,尽量避免自动装配。(zh_CN)
  9. For application level properties, best approach is to create a property file and read it in the spring bean configuration file.
  10. 对于应用程序级属性,最好的方法是创建属性文件并在 spring bean 配置文件中读取它。(zh_CN)
  11. For smaller applications, annotations are useful but for larger applications annotations can become a pain. If we have all the configuration in xml files, maintaining it will be easier.
  12. 对于较小的应用程序,注释很有用,但对于较大的应用程序,注释可能会变得很麻烦。如果我们在 xml 文件中拥有所有配置,那么维护它将更容易。(zh_CN)
  13. Use correct annotations for components for understanding the purpose easily. For services use @Service and for DAO beans use @Repository.
  14. 对组件使用正确的注释可以轻松理解目的。对于服务,使用@Service 和 DAO bean 使用@Repository。(zh_CN)
  15. Spring framework has a lot of modules, use what you need. Remove all the extra dependencies that gets usually added when you create projects through Spring Tool Suite templates.
  16. Spring 框架有很多模块,使用你需要的东西。删除通过 Spring Tool Suite 模板创建项目时通常添加的所有额外依赖项。(zh_CN)
  17. If you are using Aspects, make sure to keep the join pint as narrow as possible to avoid advice on unwanted methods. Consider custom annotations that are easier to use and avoid any issues.
  18. 如果您使用的是 Aspects,请确保尽可能缩小连接点,以避免对不需要的方法提出建议。考虑更易于使用的自定义注释并避免任何问题。(zh_CN)
  19. Use dependency injection when there is actual benefit, just for the sake of loose-coupling don’t use it because it’s harder to maintain.
  20. 当有实际好处时使用依赖注入,仅仅为了松散耦合而不使用它因为它更难维护。(zh_CN)

That’s all for Spring Framework interview questions. I hope these questions will help you in coming Java EE interview. I will keep on adding more questions to the list as soon as I found them. If you know some more questions that should be part of the list, make sure to add a comment for it and I will include it.
这就是 Spring Framework 面试问题的全部内容。我希望这些问题可以帮助您进行 Java EE 访谈。我一发现就会在列表中继续添加更多问题。如果您知道应该成为列表一部分的更多问题,请确保为其添加注释,我将包含它。(zh_CN)

面向开发人员的SQL数据库性能调优

SQL 性能调优可能是一项非常困难的任务,尤其是在处理大规模数据时,即使是最微小的变化也会对性能产生巨大的(正面或负面)影响。

在中型和大型公司中,大多数 SQL 性能调优将由数据库管理员(DBA)处理。但请相信我,有很多开发人员(https://www.toptal.com/sql),他们必须执行类似DBA的任务。此外,在许多公司中,我见过有DBA,他们往往很难与开发人员合作 – 这些职位只需要不同的问题解决方式,这可能会导致同事之间的分歧。

在处理大规模数据时,即使是最微小的变化也会对性能产生巨大影响。

最重要的是,企业结构也可以发挥作用。假设 DBA 团队位于 10 楼,所有数据库都在,而开发人员在 15 楼,甚至在完全独立的报告结构下的不同建筑物中 – 在这些条件下很难顺利合作。

在本文中,我想完成两件事:

  1. 为开发人员提供一些开发人员端的 SQL 性能调优技术。
  2. 解释开发人员和 DBA 如何有效地协同工作。

SQL 性能调优(在代码库中):索引

如果你是数据库的全新成员,甚至会问自己“什么是 SQL [性能调优](https://www.toptal.com/sql-server/how-to-tune-microsoft-sql-server-for-性能)?“,您应该知道索引是调整SQL数据库的有效方法,在开发过程中经常被忽略。在基本术语中,[index](https://en.wikipedia.org/wiki/Database_index)是一种数据结构,它通过提供快速随机查找和有序访问有序记录来提高数据库表上数据检索操作的速度。这意味着,一旦创建了索引,就可以比以前更快地选择或排序行。

索引还用于定义主键或唯一索引,以确保没有其他列具有相同的值。当然,数据库索引是一个非常有趣的话题,我无法用这个简短的描述来做到这一点(但是[这里有更详细的报道](http://stackoverflow.com/questions/1108/how-does -database 索引工作/ 1130#1130))。

如果您不熟悉索引,我建议您在构建查询时使用此图表:

This diagram illustrates a few SQL performance tuning tips every developer should know.

基本上,目标是索引主要的搜索和排序列。

请注意,如果您的表经常被敲打INSERT, UPDATE, 和DELETE, 索引时应该小心 – 因为所有索引需要,你最终会降低[性能下降](http://stackoverflow.com/questions/141232/how-many-database-indexes-is-too-many/141243#141243)在这些操作之后进行修改。

此外,DBA 经常删除其 SQL 索引,然后执行百万行以上的批量插入[加快插入过程](http://stackoverflow.com/questions/13700575/is-a-good-practice-to-disable-指数先于插入的一对多-记录上-SQL-SE)。插入批处理后,它们会重新创建索引。但请记住,删除索引会影响该表中运行的每个查询;因此,只有在使用单个大插入时才建议使用此方法。

SQL 调优:SQL Server 中的执行计划

顺便说一句:SQL Server 中的执行计划工具可用于创建索引。

它的主要功能是以图形方式显示 SQL Server 查询优化器选择的数据检索方法。如果你以前从未见过它们,那就是[详细的演练](https://youtu.be/lH2_SI04PWQ)。

要检索执行计划(在 SQL Server Management Studio 中),只需在运行查询之前单击“包含实际执行计划”(CTRL + M)。

之后,将出现名为“执行计划”的第三个选项卡。您可能会看到检测到的缺失索引。要创建它,只需右键单击执行计划并选择“缺少索引详细信息…”。就这么简单!

This screenshot demonstrates one of the performance tuning techniques for your SQL database.

(点击放大

SQL 调优:避免编码循环

想象一下,1000 个查询按顺序锤击您的数据库的场景。就像是:

for (int i = 0; i < 1000; i++)
{
    SqlCommand cmd = new SqlCommand("INSERT INTO TBL (A,B,C) VALUES...");
    cmd.ExecuteNonQuery();
}

您应该[在代码中避免此类循环](http://codeutopia.net/blog/2010/10/07/optimizing-sql-removing-queries-inside-loops/)。例如,我们可以使用唯一的转换上面的代码段INSERT 要么UPDATE 具有多个行和值的语句:

INSERT INTO TableName (A,B,C) VALUES (1,2,3),(4,5,6),(7,8,9) -- SQL SERVER 2008

INSERT INTO TableName (A,B,C) SELECT 1,2,3 UNION ALL SELECT 4,5,6 -- SQL SERVER 2005

UPDATE TableName SET A = CASE B
        WHEN 1 THEN 'NEW VALUE'
        WHEN 2 THEN 'NEW VALUE 2'
        WHEN 3 THEN 'NEW VALUE 3'
    END
WHERE B in (1,2,3)

确保你的WHERE 子句避免在存储值与现有值匹配时更新存储值。这种简单的优化可以通过仅更新数百行而不是数千行来显着提高 SQL 查询性能。例如:

UPDATE TableName
SET A = @VALUE
WHERE
      B = 'YOUR CONDITION'
            AND A <> @VALUE -- VALIDATION

[相关子查询](https://en.wikipedia.org/wiki/Correlated_subquery)是使用父查询中的值的子查询。这种SQL查询倾向于[逐行]运行(http://technet.microsoft.com/en-us/library/ms187638(v = sql.105).aspx),对于每行返回一次外部查询,从而降低 SQL 查询性能。新的 SQL 开发人员经常被抓住以这种方式构建他们的查询 – 因为它通常是简单的路径。

以下是相关子查询的示例:

SELECT c.Name,
       c.City,
       (SELECT CompanyName FROM Company WHERE ID = c.CompanyID) AS CompanyName
FROM Customer c

特别是,问题是内部查询(SELECT CompanyName…) 为外部查询返回的* each *行运行(SELECT c.Name…). 但为什么要过去Company 对于外部查询处理的每一行,一次又一次?

更高效的 SQL 性能调优技术是将相关子查询重构为连接:

SELECT c.Name,
       c.City,
       co.CompanyName
FROM Customer c
    LEFT JOIN Company co
        ON c.CompanyID = co.CompanyID

在这种情况下,我们过去了Company 表只是一次,在开始时,和它一起加入Customer 表。从那时起,我们可以选择我们需要的值(co.CompanyName) 更有效率。

SQL 调优:选择 Sparingly

我最喜欢的 SQL 优化技巧之一是避免SELECT *! 相反,您应该单独包含所需的特定列。再次,这听起来很简单,但我看到这个错误到处都是。考虑一个包含数百列和数百万行的表 – 如果您的应用程序只需要几列,那么查询* all *数据就没有意义。这是对资源的巨大浪费。 (_有关更多问题,请参阅[此处](http://stackoverflow.com/questions/3639861/why-is-select-considered-harmful#answer-3639964)。_)

例如:

SELECT * FROM Employees

vs.

SELECT FirstName, City, Country FROM Employees

如果您确实需要每一列,请明确列出每一列。这不是一个规则,而是一种防止未来系统错误和额外 SQL 性能调整的方法。例如,如果您正在使用INSERT... SELECT... 并且通过添加新列来更改源表,即使目标表不需要该列,也可能遇到问题,例如:

INSERT INTO Employees SELECT * FROM OldEmployees

Msg 213, Level 16, State 1, Line 1
Insert Error: Column name or number of supplied values does not match table definition.

要避免 SQL Server 出现此类错误,您应该单独声明每个列:

INSERT INTO Employees (FirstName, City, Country)
SELECT Name, CityName, CountryName
FROM OldEmployees

但请注意,有些情况下使用SELECT * 可能是合适的。例如,使用临时表 – 这将引导我们进入下一个主题。

SQL 调优:临时表的明智使用(#Temp)

[临时表](http://www.tutorialspoint.com/sql/sql-temporary-tables.htm)通常会增加查询的复杂性。如果您的代码可以用简单,直接的方式编写,我建议避免使用临时表。

但是如果你有一个带有一些数据操作的存储过程*不能用单个查询来处理,你可以使用临时表作为中介来帮助你生成最终结果。

当您必须加入一个大表并且所述表上有条件时,您可以通过在临时表中传输数据,然后在* that *上进行连接来提高数据库性能。您的临时表将比原始(大)表具有更少的行,因此连接将更快完成!

这个决定并不总是直截了当,但是这个例子将让您了解可能需要使用临时表的情况:

想象一下拥有数百万条记录的客户表。您必须在特定区域进行联接。你可以通过使用 a 来实现这一点SELECT INTO 语句然后加入临时表:

SELECT * INTO #Temp FROM Customer WHERE RegionID = 5
SELECT r.RegionName, t.Name FROM Region r JOIN #Temp t ON t.RegionID = r.RegionID

(注意:一些 SQL 开发人员也避免使用SELECT INTO 创建临时表,说该命令锁定 tempdb 数据库,禁止其他用户创建临时表。幸运的是,这是[在 7.0 及更高版本中修复](http://stackoverflow.com/questions/1302670/sql-server-select-into-and-blocking-with-temp-tables#answer-1302787)。)

作为临时表的替代方法,您可以考虑将子查询用作表:

SELECT r.RegionName, t.Name FROM Region r
JOIN (SELECT * FROM Customer WHERE RegionID = 5) AS t
ON t.RegionID = r.RegionID

可是等等!第二个查询存在问题。如上所述,我们应该只在子查询中包含我们需要的列(即,不使用SELECT *). 考虑到这一点:

SELECT r.RegionName, t.Name FROM Region r
JOIN (SELECT Name, RegionID FROM Customer WHERE RegionID = 5) AS t
ON t.RegionID = r.RegionID

所有这些 SQL 片段都将返回相同的数据。但是使用临时表,我们可以在临时表中创建一个索引来提高性能。有一些很好的讨论[这里](http://stackoverflow.com/questions/11169550/is-there-a-speed-difference-between-cte-subquery-and-temp-tables/11169910#11169910)之间的差异临时表和子查询。

最后,当你完成临时表时,删除它以清除 tempdb 资源,而不是等待它被自动删除(就像你终止与数据库的连接时一样):

DROP TABLE #temp

SQL 调优:“我的记录存在吗?”

这种 SQL 优化技术涉及到的使用EXISTS(). 如果要检查记录是否存在,请使用EXISTS() 代替COUNT(). 而COUNT() 扫描整个表格,计算符合条件的所有条目,EXISTS() 一看到它需要的结果就会退出。这将为您提供[更好的性能和更清晰的代码](http://sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/exists-vs-count-the-battle-never-ends.aspx)。

IF (SELECT COUNT(1) FROM EMPLOYEES WHERE FIRSTNAME LIKE '%JOHN%') > 0
    PRINT 'YES'

vs.

IF EXISTS(SELECT FIRSTNAME FROM EMPLOYEES WHERE FIRSTNAME LIKE '%JOHN%')
    PRINT 'YES'

SQL Server 2016 的 SQL 性能调优

由于使用 SQL Server 2016 的 DBA 可能知道,该版本标志着[默认和兼容性管理]的重要转变(https://www.sqlshack.com/query-optimizer-changes-in-sql-server-2016-explained /)。作为一个主要版本,它当然会带来新的查询优化,但现在可以通过简化控制它们是否被使用sys.databases.compatibility_level.

SQL 性能调优(在 Office 中)

SQL 数据库管理员(DBA)和开发人员经常会遇到与数据和非数据相关的问题。根据我的经验,这里有一些关于如何相处和有效合作的提示(双方)。

SQL performance tuning goes beyond the codebase when DBAs and developers have to work together effectively.

开发人员的数据库优化:

1.

如果您的应用程序突然停止工作,则可能不是数据库问题。例如,您可能遇到网络问题。在指责 DBA 之前调查一下!

2.

即使您是忍者 SQL 数据建模者,也请 DBA 帮助您处理关系图。他们有很多东西要分享和提供。

3.

DBA 不喜欢快速变化。这很自然:他们需要整体分析数据库,并从各个角度检查任何变化的影响。列中的简单更改可能需要一周才能实现 – 但这是因为错误可能会成为公司的巨大损失。耐心一点!

4.

不要让 SQL DBA 在生产环境中进行数据更改。如果要访问生产数据库,则必须对所有自己的更改负责。

SQL Server DBA 的数据库优化:

1.

如果您不喜欢人们向您询问数据库,请为他们提供实时状态面板。 [开发人员](https://www.toptal.com/sql-server)总是怀疑数据库的状态,这样的面板可以节省每个人的时间和精力。

2.

在测试/质量保证环境中帮助开发人员。通过对真实数据的简单测试,可以轻松地模拟生产服务器。对于其他人和您自己来说,这将节省大量时间。

3.

开发人员整天都在经常更改业务逻辑的系统上花费一整天。尝试理解这个世界更灵活,并能够在关键时刻打破一些规则。

4.

SQL 数据库不断发展。必须将数据迁移到新版本的那一天。开发人员依靠每个新版本的重要新功能。不要拒绝接受他们的更改,而是提前计划并为迁移做好准备。

了解基础知识

什么是 DBMS 中的查询处理?

像 SQL Server 这样的数据库管理系统必须将您提供的 SQL 查询转换为他们必须执行的实际指令,以读取或更改数据库中的数据。在处理之后,数据库引擎然后还尝试在可能的情况下自动优化查询。

什么是 SQL Server 中的查询优化?

查询优化是指开发人员或数据库引擎以这样的方式更改查询,即 SQL Server 能够更有效地返回相同的结果。有时候使用 EXISTS()而不是 COUNT()很简单,但有时候需要用不同的方法重写查询。

什么是 SQL Server 中的性能调优?

性能调优包括查询优化,SQL 客户端代码优化,数据库索引管理,以及在另一种意义上,开发人员和 DBA 之间更好的协调。

SQL 中的索引有什么用?

索引跟踪表数据的目标子集,以便可以更快地完成选择和排序,而服务器不必查看该表的每个最后一位数据。

为什么 EXISTS()比 COUNT()更快?

EXISTS()一找到匹配的行就会停止处理,而 COUNT()必须计算每一行,无论你最后是否真的需要这个细节。

关于作者

[Rodrigo Koch,巴西](https://www.toptal.com/resume/rodrigo-koch)

会员自 2012 年 6 月 24 日起

Rodrigo 是使用 C#的.NET Web 应用程序的 Microsoft 认证专家。他的双重国籍使他成为德国和巴西开发商的宝贵资源。他具有强大的开发和故障排除技能,并且具有匹配的组合;他广泛的知名客户包括雀巢,Chartis 保险和卡西欧巴西。如今,他在三星拉丁美洲工作。 [[点击继续…]](https://www.toptal.com/resume/rodrigo-koch)

node环境下如何使用jquery?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cvper/article/details/79576071

(测试环境:node 7.6.0 npm 5.6.0 jquery 3.3.1 jsdom 11.6.2)

第一步,下载 jquery 包

命令:npm install jquery

第二步 , 下载 jsdom 包

命令:npm install jsdom

第三步,我们新建一个 index.js

代码如下:

const jsdom = require("jsdom");

const { JSDOM } = jsdom;

const { window } = newJSDOM(`<!DOCTYPE html>`);

const $ = require("jQuery")(window);

console.log($); //测试 jquery 是否可以正常工作

第四步:执行命令 node index.js

查看输出信息:

证明 jquery 可以正常使用了;

where子句的顺序在SQL中是否重要

不,这个顺序无关紧要(或至少:无所谓)。

任何体面的查询优化器都会查看所有部分WHERE 子句并找出满足该查询的最有效方法。

我知道 SQL Server 查询优化器会选择一个合适的索引 – 无论你有两个条件的顺序。我假设其他 RDBMS 将有类似的策略。

重要的是你是否有适合的指数!

对于 SQL Server,如果您有以下情况,它可能会使用索引:

  • 一个索引(LastName, FirstName)
  • 一个索引(FirstName, LastName)
  • 关于公正的指数(LastName), 要不就(FirstName) (或两者)

另一方面 – 再次为 SQL Server – 如果您使用SELECT * 从表中获取所有列,并且表格相当小,然后查询优化器很可能只执行表(或聚簇索引)扫描而不是使用索引(因为查找到完整数据页面得到所有其他列只是很快就太贵了)。

如何捕获express框架app.listen的异常?

问题背景

由于在启动项目时会出现

uncaught exception: Error: listen EADDRINUSR 155.145.111.11:45621 … …

解决方法

所以想捕获 listen 的异常。但在网上查了之后都是用的 process.on(‘uncaughtexception’,function)此方法。 有没有直接捕获 listen 的异常的方法呀,求助。

1、process.on(‘uncaughtexception’, callback) 是进程级别的异常捕获;
2、app.listen(port, callback); 这里的 callback 可以理解为,整个框架都是通过一个回调函数来处理 HTTP 请求,里面进程 MVC 等各种设计;

来看看 app.listen 到底做了什么:https://github.com/expressjs/express/blob/master/lib/application.js#L617。

====== 正义分割线

通过 app.listen 我们其实得到一个 server 对象,通过监听 server 对象的错误事件可以获取到错误信息;

server.on("error", e => {
  if (e.code === "EADDRINUSE") {
    console.log("Address in use, retrying...");
    setTimeout(() => {
      server.close();
      server.listen(PORT, HOST);
    }, 1000);
  }
});
  • 通过 server.listening 方法可以提前判断端口是否被占用;
  • listen 时指定端口为 0 ,会随机分配一个可用的端口

Spring事务 数据库事务隔离级别解释

数据库并发会引起下面问题

  1. 脏读
    > 正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
  2. 不可重复读
    > 是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)
    例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。
  3. 幻读
    > 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象
    发生了幻觉一样。
    例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。

不可重复读的重点是修改 :
同样的条件 ,   你读取过的数据 ,   再次读取出来发现值不一样了
幻读的重点在于新增或者删除
同样的条件 ,   第 1 次和第 2 次读出来的记录数不一样

数据库事务隔离级别

数据库事务的隔离级别有 4 个,由低到高依次为 Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读  、不可重复读  、幻读 这几类问题。

√: 可能出现     ×: 不会出现

级别 脏读 不可重复读 幻读 锁定情况
Read uncommitted 隔离级别最低,并发性能高
Read committed — Oracle,MSSQL × 锁定正在读取的行
Repeatable read — MySQL × × 锁定所读取的所有行
Serializable × × × 锁表

Spring事务传播行为

在TransactionDefinition接口中定义了七个事务传播行为。

  1. PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。(spring的事务传播方式默认是PROPAGATION_REQUIRED)

  2. PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

  3. PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

  4. PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

  5. PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。

  6. PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常

  7. PROPAGATION_NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行

事务是逻辑处理原子性的保证手段,通过使用事务控制,可以极大的避免出现逻辑处理失败导致的脏数据等问题。

事务最重要的两个特性,是事务的传播级别和数据隔离级别。传播级别定义的是事务的控制范围,事务隔离级别定义的是事务在数据库读写方面的控制范围。

Spring管理事务的方式

  1. 声明式事务

    基于 AOP,将具体业务逻辑与事务处理解耦。声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中声明式事务用的比较多。
    声明式事务有两种方式,一种是在配置文件(xml)中做相关的事务规则声明,另一种是基于 @Transactional 注解的方式

  2. 编程式事务

Spring配置声明式事务:

  • 配置DataSource
  • 配置事务管理器
  • 事务的传播特性
  • 那些类那些方法使用事务

Java加解密算法

Spring 配置事务的方式

  1. 注解式事务
  2. 使用AOP的方式实现事务的配置

xmake-vscode插件开发过程记录

最近打算给xmake写一些 IDE 和编辑器的集成插件,发现 vscode 的编辑器插件比较容易上手的,就先研究了下 vscode 的插件开发流程,并且完成了xmake-vscode插件的开发。

我们先来看几张最后的效果图:

语法高亮和自动补全

状态栏

statusbar

要实现上面的效果,其实并不复杂,首先我们先来简单介绍下,vscode 的插件开发的基本流程:

安装插件开发环境

安装 cnpm

由于国内环境比较复杂,直接用 npm 安装也许很慢或者访问不稳定,因此这里先安装了 cnpm 去默认使用淘宝的镜像源。

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

创建空工程

通过 cnpm 去安装 yo 工具,用来创建一个 vscode 插件的空工程

$ cnpm install -g yo generator-code
$ yo code

大体的源码结构如下:

选择创建项目后有四个输入和一个选择:

  • 输入你扩展的名称 xmake-vscode
  • 输入一个标志(项目创建的文件名称用这个)xmake-vscode
  • 输入对这个扩展的描述
  • 输入以后要发布用到的一名称(和以后再发布时候有一个名字是对应上的)tboox
  • 是问你要不要创建一个 git 仓库用于版本管理

创建完成后的空工程,我们可以用 vscode 直接打开,然后进行调试加载运行下:

加载起来后,敲 F1 打开命令窗口,运行默认的 hello world 测试命令:


到此,一个简答的 demo 插件就搞定了,接下来我们简单介绍下如何发布这个插件到 vscode 的 market 上去。

创建发布者

首先我们需要在marketplace.visualstudio.com上注册一个账号,创建一个发布者,这里我取名为 tboox

然后,我们需要在自己的账号里面,添加一个 Personal Access Token(地址:https://[your name].visualstudio.com/_details/security/tokens,注意 Token 只显示一次,最好自己保存一份)

接着,我们安装下 vsce 这个工具,用于 vscode 的插件工程打包编译和发布。

$ cnpm install -g vsce

安装好 vsce 后,我们先创建一个发布者,这里为 tboox,输入刚刚 market 账号里面提供的 token 进行绑定。

$ vsce create-publisher (publisher name)

构建发布

最后,只需要通过下面命令进行打包或者发布就行了,如果仅仅打个本地包,拖入 vscode 加载测试,可以运行:

$ vsce package

这将会生成一个类似xmake-vscode-0.0.1.vslx的插件包文件,用 vscode 可直接加载运行。

如果,我们已经开发完了插件,想要发布到 market 市场,可以执行:

$ vsce publish [version]

这个时候,我们就可以在xmake-vscode on marketplace上看到你的插件了,用户也可以直接通过 vscode 进行搜索和安装使用。

插件开发详解

插件的加载机制

插件通过工程根目录 extension.json 中配置的 activationEvents 进行触发,例如:

{
    "activationEvents": [
        "workspaceContains:xmake.lua",
        "onCommand:xmake.sayHello"
    ]
}

当 vscode 打开带有xmake.lua的目录或者执行xmake.XXX相关命令的时候,都会触发加载 xmake-vscode 插件,然后调用src/extension.ts中的 activate 入口函数,进行插件的加载和初始化。

export functionactivate(context: vscode.ExtensionContext) {let disposable = vscode.commands.registerCommand('xmake.sayHello', () => {
        vscode.window.showInformationMessage('Hello XMake!');
    });

    context.subscriptions.push(disposable);
}

上述代码,在加载插件的时候,注册sayHello命令,去显示Hello XMake!提示信息。

创建自定义输出

vscode 通过创建 OutputChannel 来输出自己的日志信息,代码如下:

import * as vscode from 'vscode';

let log = vscode.window.createOutputChannel("xmake/log");
log.show();
log.appendLine("hello xmake!");

在创建的时候可以指定一个 label 名,用于区分不同的输出通道,最后显示的结果如下:

需要注意的是,必须执行log.show(),输出才会被显示出来,并且输出行为是带缓存刷新的,并不会实时输出,也不支持色彩高亮输出。

创建和控制终端

之前,xmake-vscode 就是采用 channel 的方式来输出 xmake 的构建信息,效果不是很理想,因此后来改用了终端直接执行的方式,可以看下下面的效果图:

那如何控制终端,执行自己的命令呢,其实也非常简单:

let terminal = vscode.window.createTerminal({name: "xmake"});
terminal.show(true);
terminal.sendText("xmake");

上面的代码,通过创建一个 label 名为 xmake 的独立终端,然后发送执行命令:xmake,去让终端执行 xmake 进行项目的构建,当然如果要显示出来,还是要先调用下terminal.show(true)

添加和读取全局配置

xmake-vscode 里面增加了一些全局 vscode 配置项,用于控制 xmake-vscode 插件的行为,配置清单是在 package.json 文件中进行描述的,例如:

{
    "configuration": {
        "type": "object",
        "title": "XMake configuration",
        "properties": {
            "xmake.logLevel": {
                "type": "string",
                "default": "normal",
                "description": "The Log Level: normal/verbose/minimal",
                "enum": [
                    "verbose",
                    "normal",
                    "minimal"
                ]
            },
            "xmake.buildDirectory": {
                "type": "string",
                "default": "${workspaceRoot}/build",
                "description": "The Build Output Directory"},
            "xmake.androidNDKDirectory": {
                "type": "string",
                "default": "",
                "description": "The Android NDK Directory"}
        }
    }
}

上述配置,增加了三个配置项,都在xmake.域下面,可在 vscode 配置中直接搜索 xmake 相关字样就能方便找到。

读取配置也很方便,只要获取 xmake 相关域配置,进行读取就行了:

const config = vscode.workspace.getConfiguration('xmake');
config.get("buildDirectory");

创建状态栏

状态栏上的按钮是可以响应之前创建的那些命令的,例如:xmake.sayHello等,下面我们在状态栏上创建一个 debug 按钮,用来调试运行 xmake 构建的程序:

let debugButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.5);

debugButton.command = 'xmake.onDebug';
debugButton.text = `$(bug)`;
debugButton.tooltip = "Debug the given target";
debugButton.show();

createStatusBarItem 中第二个参数 4.5 用于控制按钮在状态栏上的布局顺序,创建好后,再设置下一些基础属性就行了,这里按钮的文本直接通过$(bug)设置了一个图标来显示,更加的直观。

更多 vscode 内置支持的图标,可以自己从octicons上面去找。

点击这个按钮,将会触发xmake.onDebug命令,然后在终端上执行xmake run -d命令,去运行调试程序。

添加选项输入列表

xmake-vscode的状态栏上,我们还增加了几个快速配置的状态按钮,用于快速切换不同的平台、架构、编译模式,例如:

这个时候,需要有个选项选择列表的支持,在点击按钮后,列出可以选择的几个选项,然后选择切换,那如何创建这个选项列表呢,直接上代码:

let items: vscode.QuickPickItem[] = [];
items.push({label: "linux", description: "The Linux Platform"});
items.push({label: "macosx", description: "The MacOS Platform"});
items.push({label: "windows", description: "The Windows Platform"});
items.push({label: "android", description: "The Android Platform"});
items.push({label: "iphoneos", description: "The iPhoneOS Platform"});
items.push({label: "watchos", description: "The WatchOS Platform"});
items.push({label: "mingw", description: "The MingW Platform"});
items.push({label: "cross", description: "The Cross Platform"});


const chosen: vscode.QuickPickItem|undefined = await vscode.window.showQuickPick(items);
if (chosen) {


    platButton.text = chosen.label;
}

自定义语法高亮

语法高亮完全可以通过配置文件来搞定,不用写代码,当然也可以在代码中动态配置,这样稍微繁琐些。

xmake-vscode 里面需要处理工程 xmake.lua 描述文件的语法高亮,因此这边在 package.json 里面先定义了一个叫 xmake 的语言类型,如果编辑器打开xmake.lua文件,就会对其进行语法高亮处理。

{
    "contributes": {
        "languages": [
            {
                "id": "xmake",
                "filenames": [
                    "xmake.lua"
                ],
                "aliases": [
                    "XMake"
                ],
                "configuration": "./languages/xmake-configuration.json"}
        ],
        "grammars": [
            {
                "language": "xmake",
                "scopeName": "source.xmake",
                "path": "./languages/xmake-grammars.json"}
        ]
    }
}

跟语法高亮相关的描述,都放置在/languages/xmake-grammars.json中,用 json 来描述,我们也可以用 xml 的格式来描述,但是这样可读性不是很好。

xmake-grammars.json中的描述规则,我们摘录自 lua 的 grammars 文件,因为xmake.lua本身就是基于 lua 语法的,例如,我们匹配'xxx'单引号字符串的规则,进行字符串的高亮输出。

{
    "begin": "'",
    "beginCaptures": {
        "0": {
            "name": "punctuation.definition.string.begin.xmake"}
    },
    "end": "'",
    "endCaptures": {
        "0": {
            "name": "punctuation.definition.string.end.xmake"}
    },
    "name": "string.quoted.single.xmake",
    "patterns": [
        {
            "include": "#escaped_char"}
    ]
}

自动补全的实现

代码的自动提示和补全比较麻烦下,需要写个自定义的 class,通过 languages 进行注册:

vscode.languages.registerCompletionItemProvider("xmake", new Completion());

这里我们定义了一个 Completion 类,注册到 xmake 语言上去,xmake 语言定义,就是刚才讲的在 package.json 中的配置。

然后我们实现下这个 Completion 类:

export class Completion implements vscode.CompletionItemProvider {


    public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable<vscode.CompletionItem[]> {

        // 获取当前输入的单词文本let wordAtPosition = document.getWordRangeAtPosition(position);
        var currentWord = '';
        if (wordAtPosition && wordAtPosition.start.character < position.character) {
            var word = document.getText(wordAtPosition);
            currentWord = word.substr(0, position.character - wordAtPosition.start.character);
        }


        returnnew Promise(function(resolve, reject) {
            Promise.all([
                getLuaKeywordsSuggestions(currentWord),
                getXMakeCommandsSuggestions(currentWord)
            ]).then(function(results) {var suggestions = Array.prototype.concat.apply([], results);
                resolve(suggestions);
            }).catch(err => { reject(err); });
        });
    }


    public resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken): Thenable<vscode.CompletionItem> {

        // 对每个候选文本增加文档描述returnnew Promise(function(resolve, reject) {
            item.documentation = "xxxxxxxxxxx";
            resolve(item);
         });
    }
}

这部分代码比较多,就不完全贴出来了,完整实现,可参考:completion.ts

结语

本文讲述的一些 vscode 插件代码都来自xmake-vscode,有兴趣的同学可以直接参考源码,写个自己的插件。

原文出处:http://tboox.org/cn/2017/10/11/xmake-vscode/

Java Spring框架面试总结

Spring IoC 和 DI 的理解

  1. Ioc(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理,简单点说,就是创建对象的控制权被反转到 Spring 框架了。
  2. DI(Dependency Injection,依赖注入),在 Spring 框架负责创建 Bean 对象时,动态的将其依赖对象注入到该 Bean 对象组件中。
  3. 两者的区别:Ioc 控制反转,指将对象的创建权反转到 Spring 容器;DI 依赖注入,指 Spring 创建对象时,将对象的依赖属性通过配置进行注入。

Spring Bean 的作用域(Scope)

  1. singleton (默认的作用域), 当一个 Bean 的作用域为 singleton,那么 Spring Ioc 容器只会存在一个共享的 bean 实例
  2. prototype, 每次获取该 bean 时,都会创建一个新的 bean 实例。

  3. request, 在一次 HTTP 请求中,只会创建一个 Bean 实例。

  4. session, 在一个 HTTP Session 中, 只会创建一个 bean 实例。
  5. global session

Spring Bean 属性注入方式

  1. 基于构造方法注入依赖
  2. 基于 setter 方法注入依赖
  3. 基于字段注入依赖(通过反射直接注入到字段属性)

 构造方法和 set 方法可以组合用于同一个 Bean 对象,Spring 文档推荐对强制依赖项使用构造函数注入,对可选依赖项使用 setter 方法注入。

基于字段注入的方法,虽然看起来更简单清晰,但不推荐使用,有以下缺点:

  • 不能跟构造函数注入一样,创建不可变的对象。
  • 只能靠 DI 容器反射注入属性,不能在外部注入使用
  • 真实的依赖关系隐藏在内部

Field 注入应该尽可能地去避免使用。作为替代,你应该使用构构造器注入或 Setter 注入。他们都有利有弊,需要视情况而定。当然你可以在同一个类中使用这两种方法。构造器注入更适合强制性的注入旨在不变性,Setter 注入更适合可变性的注入。

BeanFactory 接口与 ApplicationContext 接口的区别

  1. ApplicationContext 接口 继承 BeanFactory 接口,Spring 的核心工厂是 BeanFactory,BeanFactory 采取延迟加载,第一次 getBean 时才会初始化 Bean,ApplicationContext 是在加载配置文件时初始化 Bean.
  2. ApplicationContext 是对 BeanFactory 扩展,添加了国际化处理,事件传递和 bean 自动装配以及各种不同应用层的 Context 实现,现实开发中基本使用的都是 ApplicationContext,web 项目使用 WebApplicationContext,很少使用 BeanFactory.

Spring 实例化 bean 的方法

  1. 使用类构造器(默认是无参数)
  2. 使用静态工厂方法(简单工厂模式)
  3. 使用实例工厂方法(工厂方法模式)

Spring MVC 流程原理

  1. Springmvc 将所有的请求都交给 DispatcherServlet(前端控制器,他会委托应用系统的其他模块负责对请求进行真正的处理工作)。

  2. DispatcherServlet 根据请求的 URL 格式, 查询一个或多个 HandlerMapping(处理器映射器),找到处理请求的 Controller.

  3. DispatcherServlet 将请求转交给目标 Controller.
  4. Controller 进行业务逻辑处理后,返回一个 ModelAndView(模型和视图) 对象。
  5. DispatcherServlet 查询一个或多个 ViewResolver(视图解析器),找到 ModelAndView 对象指定的视图对象
  6. 视图对象负责将渲染结果显示返回给客户端。

什么是 Spring Boot ?

Spring Boot 是构建在 Spring 框架之上, 是设计用来简化 Spring 应用初始搭建及开发过程一个解决方案。它使用了特定的方式进行配置,从而是开发人员不再需要定义样本化的配置。

Spring中常见面试题

什么是 Spring

Spring 是一个开源的 Java EE 开发框架。Spring 框架的核心功能可以应用在任何 Java 应用程序中,但对 Java EE 平台上的 Web 应用程序有更好的扩展性。Spring 框架的目标是使得 Java EE 应用程序的开发更加简捷,通过使用 POJO 为基础的编程模型促进良好的编程风格。


Spring 有哪些优点

轻量级:Spring 在大小和透明性方面绝对属于轻量级的,基础版本的 Spring 框架大约只有 2MB。

控制反转(IOC):Spring 使用控制反转技术实现了松耦合。依赖被注入到对象,而不是创建或寻找依赖对象。

面向切面编程(AOP): Spring 支持面向切面编程,同时把应用的业务逻辑与系统的服务分离开来。

容器:Spring 包含并管理应用程序对象的配置,依赖关系和生命周期。

MVC 框架:Spring 的 web 框架是一个设计优良的 web MVC 框架,很好的取代了一些 web 框架。

事务管理:Spring 对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。

异常处理:Spring 提供一个方便的 API 将特定技术的异常(由 JDBC, Hibernate, 或 JDO 抛出)转化为一致的、Unchecked 异常。


Spring 框架有哪些模块

Spring 框架至今已集成了 20 多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成、Web、AOP(面向切面编程)、工具、消息和测试模块。

核心容器模块:是 spring 中最核心的模块。负责 Bean 的创建,配置和管理。主要包括:beans,core,context,expression 等模块。

Spring 的 AOP 模块:主要负责对面向切面编程的支持,帮助应用对象解耦。

数据访问和集成模块:包括 JDBC,ORM,OXM,JMS 和事务处理模块,其细节如下: JDBC 模块提供了不再需要冗长的 JDBC 编码相关了 JDBC 的抽象层。 ORM 模块提供的集成层。流行的对象关系映射 API,包括 JPA,JDO,Hibernate 和 iBatis。 OXM 模块提供了一个支持对象/ XML 映射实现对 JAXB,Castor,使用 XMLBeans,JiBX 和 XStream 的抽象层。 Java 消息服务 JMS 模块包含的功能为生产和消费的信息。 事务模块支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。

Web 和远程调用:包括 web,servlet,struts,portlet 模块。

测试模块:test

工具模块消息模块


什么是控制反转(IOC)?什么是依赖注入?

传统模式中对象的调用者需要创建被调用对象,两个对象过于耦合,不利于变化和拓展.在 spring 中,直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理,从而实现对象之间的松耦合。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。

依赖注入:对象无需自行创建或管理它们的依赖关系,IoC 容器在运行期间,动态地将某种依赖关系注入到对象之中。依赖注入能让相互协作的软件组件保持松散耦合。


BeanFactory 和 ApplicationContext 有什么区别?

Bean 工厂(BeanFactory)是 Spring 框架最核心的接口,提供了高级 Ioc 的配置机制.

应用上下文(ApplicationContext)建立在 BeanFacotry 基础之上,提供了更多面向应用的功能,如果国际化,属性编辑器,事件等等.

beanFactory 是 spring 框架的基础设施,是面向 spring 本身,ApplicationContext 是面向使用 Spring 框架的开发者,几乎所有场合都会用到 ApplicationContext.


Spring 有几种配置方式?

将 Spring 配置到应用开发中有以下三种方式:

  1. 基于 XML 的配置

  2. 基于注解的配置: Spring 在 2.5 版本以后开始支持用注解的方式来配置依赖注入。可以用注解的方式来替代 XML 方式的 bean 描述,可以将 bean 描述转移到组件类的内部,只需要在相关类上、方法上或者字段声明上使用注解即可。注解注入将会被容器在 XML 注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果

  3. 基于 Java 的配置: Spring 对 Java 配置的支持是由@Configuration 注解和@Bean 注解来实现的。由@Bean 注解的方法将会实例化、配置和初始化一个新对象,这个对象将由 Spring 的 IoC 容器来管理。@Bean 声明所起到的作用与元素类似。被@Configuration 所注解的类则表示这个类的主要目的是作为 bean 定义的资源。被@Configuration 声明的类可以通过在同一个类的内部调用@bean 方法来设置嵌入 bean 的依赖关系。

三种装配方法及选择原则

装配方式

  1. 自动装配方式
  2. 使用 XML 方式
  3. 使用 JAVA Config 方式,Spring 的 Java Config 方式是通过 @Configuration 和 @Bean 注解实现的

选择原则

  1. 最优先: 通过隐式 Bean 的发现机制和自动装配原则。基于约定配置的原则,应该优先使用。

  2. 其次:Java 接口和类中配置是在没有办法使用自动装配原则的情况下,应该考虑此类方式

  3. 最后才是 XML 方式配置。 在上述方式都无法使用的情况下,只能选择基于 XML 方式的配置。

Spring Bean 的生命周期

Bean 在 Spring 中的生命周期如下:

  1. 实例化,Spring 通过 new 关键字将一个 Bean 进行实例化,Java Bean 都有默认的构造函数,因此不需要提供构造参数。

  2. 注入依赖,Spring 根据 xml 文件中的配置通过调用 Bean 中的 setXXX 方法填入对应的属性。

  3. 事件通知,Spring 依次检查 Bean 是否实现了 BeanNameAware、BeanFactoryAware、ApplicationContextAware、BeanPostProcessor、InitializingBean 接口,如果有的话,依次调用这些接口。

  4. 使用,应用程序可以正常使用这个 Bean 了。

销毁。如果 Bean 实现了 DisposableBean 接口,就调用其 destroy 方法。

加载过程

  1. 容器寻找 Bean 的定义信息并且将其实例化。

  2. 如果允许提前暴露工厂,则提前暴露这个 bean 的工厂,这个工厂主要是返回该未完全处理的 bean.主要是用于避免单例属性循环依赖问题.

  3. 受用依赖注入,Spring 按照 Bean 定义信息配置 Bean 的所有属性。

  4. 如果 Bean 实现了 BeanNameAware 接口,工厂调用 Bean 的 setBeanName()方法传递 Bean 的 ID。

  5. 如果 Bean 实现了 BeanFactoryAware 接口,工厂调用 setBeanFactory()方法传入工厂自身。

  6. 如果 BeanPostProcessor 和 Bean 关联,那么它们的 postProcessBeforeInitialzation()方法将被调用。

  7. 如果 Bean 指定了 init-method 方法,它将被调用。

  8. 如果有 BeanPostProcessor 和 Bean 关联,那么它们的 postProcessAfterInitialization()方法将被调用

  9. 最后如果配置了 destroy-method 方法则注册 DisposableBean.

到这个时候,Bean 已经可以被应用系统使用了,并且将被保留在 Bean Factory 中知道它不再需要。 有两种方法可以把它从 Bean Factory 中删除掉。

1.如果 Bean 实现了 DisposableBean 接口,destory()方法被调用。

2.如果指定了订制的销毁方法,就调用这个方法。


Spring Bean 的作用域之间有什么区别

singleton:这种 bean 范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个 bean 的实例,单例的模式由 bean factory 自身来维护。

prototype:原形范围与单例范围相反,为每一个 bean 请求提供一个实例。

request:在请求 bean 范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean 会失效并被垃圾回收器回收。

Session:与请求范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后,bean 会随之失效。

global-session:global-session 和 Portlet 应用相关。当你的应用部署在 Portlet 容器中工作时,它包含很多 portlet。如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在 global-session 中。


请解释自动装配模式的区别

no:这是 Spring 框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在 bean 定义中用标签明确的设置依赖关系。

byName**:该选项可以根据 bean 名称设置依赖关系。当向一个 bean 中自动装配一个属性时,容器将根据 bean 的名称自动在在配置文件中查询一个匹配的 bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

byType:该选项可以根据 bean 类型设置依赖关系。当向一个 bean 中自动装配一个属性时,容器将根据 bean 的类型自动在在配置文件中查询一个匹配的 bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

constructor:造器的自动装配和 byType 模式类似,但是仅仅适用于与有构造器相同参数的 bean,如果在容器中没有找到与构造器参数类型一致的 bean,那么将会抛出异常。

autodetect:该模式自动探测使用构造器自动装配或者 byType 自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在 bean 内部没有找到相应的构造器或者是无参构造器,容器就会自动选择 byTpe 的自动装配方式。


Spring 框架中都用到了哪些设计模式

代理模式—在 AOP 和 remoting 中被用的比较多。

单例模式—在 spring 配置文件中定义的 bean 默认为单例模式。

模板方法—用来解决代码重复的问题 比如. RestTemplate, JmsTemplate, JpaTemplate。 前端控制器—Srping 提供了 DispatcherServlet 来对请求进行分发。 视图帮助(View Helper )—Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码整合在视图里。 依赖注入—贯穿于 BeanFactory / ApplicationContext 接口的核心理念。

工厂模式—BeanFactory 用来创建对象的实例。

Builder 模式- 自定义配置文件的解析 bean 是时采用 builder 模式,一步一步地构建一个 beanDefinition

策略模式:Spring 中策略模式使用有多个地方,如 Bean 定义对象的创建以及代理对象的创建等。这里主要看一下代理对象创建的策略模式的实现。 前面已经了解 Spring 的代理方式有两个 Jdk 动态代理和 CGLIB 代理。这两个代理方式的使用正是使用了策略模式。


AOP 是怎么实现的

实现 AOP 的技术,主要分为两大类:

一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;

二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

Spring AOP 的实现原理其实很简单:AOP 框架负责动态地生成 AOP 代理类,这个代理类的方法则由 Advice 和回调目标对象的方法所组成,并将该对象可作为目标对象使用。AOP 代理包含了目标对象的全部方法,但 AOP 代理中的方法与目标对象的方法存在差异,AOP 方法在特定切入点添加了增强处理,并回调了目标对象的方法。

Spring AOP 使用动态代理技术在运行期织入增强代码。使用两种代理机制:

基于 JDK 的动态代理(JDK 本身只提供接口的代理);

基于 CGlib 的动态代理。

1)JDK 的动态代理主要涉及 java.lang.reflect 包中的两个类:Proxy 和 InvocationHandler。其中 InvocationHandler 只是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态的将横切逻辑与业务逻辑织在一起。而 Proxy 利用 InvocationHandler 动态创建一个符合某一接口的实例,生成目标类的代理对象。 其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理.只能实现接口的类生成代理,而不能针对类

2)CGLib 采用底层的字节码技术,为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类的调用方法,并顺势织入横切逻辑.它运行期间生成的代理对象是目标类的扩展子类.所以无法通知 final 的方法,因为它们不能被覆写.是针对类实现代理,主要是为指定的类生成一个子类,覆盖其中方法.

在 spring 中默认情况下使用 JDK 动态代理实现 AOP,如果 proxy-target-class 设置为 true 或者使用了优化策略那么会使用 CGLIB 来创建动态代理.Spring   AOP 在这两种方式的实现上基本一样.以 JDK 代理为例,会使用 JdkDynamicAopProxy 来创建代理,在 invoke()方法首先需要织入到当前类的增强器封装到拦截器链中,然后递归的调用这些拦截器完成功能的织入.最终返回代理对象.

http://zhengjianglong.cn/2015/12/12/Spring/spring-source-aop/


介绍 spring 的 IOC 实现

Spring   IOC 主要负责创建和管理 bean 及 bean 之间的依赖关系.

Spring   IOC 的可分为:IOC 容器的初始化和 bean 的加载.

在 IOC 容器阶段主要是完成资源的加载(如定义 bean 的 xml 文件),bean 的解析及对解析后得到的 beanDefinition 的进行注册.以 xmlBeanFactory 为例,XmlBeanFactory 继承了 DefaultListableBeanFactory,XmlBeanFactory 将读取 xml 配置文件,解析 bean 和注册解析后的 beanDefinition 工作交给 XmlBeanDefinitionReader(是 BeanDefinitionReader 接口的一个个性化实现)来执行.spring 中定义了一套资源类,将文件,class 等都看做资源.

1)所以首先是将 xml 文件转化为资源然后用 EncodeResouce 来封装,该功能主要时考虑 Resource 可能存在编码要求的情况,如 UTF-8 等.

2)然后根据 xml 文件判断 xml 的约束模式,是 DTD 还是 Schema,以及寻找模式文档(验证文件)的方法(EntityResolver,这部分采用了代理模式和策略模式). 完成了前面所有的准备工作以后就可以正式的加载配置文件,获取 Docoment 和解析注册 BeanDefinition.Docoment 的获取以及 BeanDefinition 的解析注册并不是由 XmlBeanDefinitionReader 完成,XmlBeanDefinitionReader 只是将前面的工作完成以后文档加载交给 DefaultDocumentLoader 类来完成.而解析交给了 DefaultBeanDefinitionDocumentReader 来处理.bean 标签可以分为两种,一种是 spring 自带的默认标签,另一种就是用户自定义的标签.所以 spring 针对这两种情况,提供了不同的解析方式. 每种 bean 的解析完成后都会先注册到容器中然后最后发出响应事件,通知相关的监听器这个 bean 已经注册完成了.

bean 的加载http://zhengjianglong.cn/2015/12/06/Spring/spring-source-ioc-bean-parse/


springMVC 流程具体叙述下

当应用启动时,容器会加载 servlet 类并调用 init 方法. 在这个阶段,DispatcherServlet 在 init()完成初始化参数 init-param 的解析和封装,相关配置,spring 的 WebApplicationContext 的初始化即完成 xml 文件的加载,bean 的解析和注册等工作,另外为 servlet 功能所用的变量进行初始化,如:handlerMapping,viewResolvers 等.

当用户发送一个请求时,首先根据请求的类型调用 DispatcherServlet 不同的方法,这些方法都会转发到 doService()中执行.在该方法内部完成以下工作:

1)spring 首先考虑 multipart 的处理,如果是 MultipartContent 类型的 request,则将该请求转换成 MultipartHttpServletRequest 类型的 request.

2)根据 request 信息获取对应的 Handler. 首先根据 request 获取访问路径,然后根据该路径可以选择直接匹配或通用匹配的方式寻找 Handler,即用户定义的 controller. Handler 在 init()方法时已经完成加载且保存到 Map 中了,只要根据路径就可以得到对应的 Handler. 如果不存在则尝试使用默认的 Handler. 如果还是没有找到那么就通过 response 向用户返回错误信息.找到 handler 后会将其包装在一个执行链中,然后将所有的拦截器也加入到该链中.

4)如果存在 handler 则根据当前的 handler 寻找对应的 HandlerAdapter. 通过遍历所有适配器来选择合适的适配器.

5)SpringMVC 允许你通过处理拦截器 Web 请求,进行前置处理和后置处理.所以在正式调用 Handler 的逻辑方法时,先执行所有拦截器的 preHandle()方法.

6)正式执行 handle 的业务逻辑方法 handle(),返回 ModelAndView.逻辑处理是通过适配器调用 handle 并返回视图.这过程其实是调用用户 controller 的业务逻辑.

8)调用拦截器的 postHandle()方法,完成后置处理.

9)根据视图进行页面跳转.该过程首先会根据视图名字解析得到视图,该过程支持缓存,如果缓存中存在则直接获取,否则创建新的视图并在支持缓存的情况下保存到缓冲中.

10)过程完成了像添加前缀后缀,设置必须的属性等工作.最后就是进行页面跳转处理.

11)调用拦截器的 afterComplection()


AOP 相关概念

方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是 J2EE 应用中一个很好的横切关注点例子。方面用 Spring 的 Advisor 或拦截器实现。

连接点(Joinpoint): 程序执行过程中明确的点,如方法的调用或特定的异常被抛出。

通知(Advice):在特定的连接点,AOP 框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多 AOP 框架包括 Spring 都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。Spring 中定义了 4 个 advice.Interception Around(MethodInterceptor)、Before(MethodBeforeAdvice)、After Returning(AfterReturningAdvice)、After(AfterAdvice)。

切入点(Pointcut): 一系列连接点的集合。AOP 框架必须允许开发者指定切入点:例如,使用正则表达式。 Spring 定义了 Pointcut 接口,用来组合 MethodMatcher 和 ClassFilter,可以通过名字很清楚的理解, MethodMatcher 是用来检查目标类的方法是否可以被应用此通知,而 ClassFilter 是用来检查 Pointcut 是否应该应用到目标类上

引入(Introduction): 添加方法或字段到被通知的类。 Spring 允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified 接口,来简化缓存。Spring 中要使用 Introduction, 可有通过 DelegatingIntroductionInterceptor 来实现通知,通过 DefaultIntroductionAdvisor 来配置 Advice 和代理类要实现的接口

目标对象(Target Object): 包含连接点的对象。也被称作被通知或被代理对象。

POJOAOP 代理(AOP Proxy): AOP 框架创建的对象,包含通知。 在 Spring 中,AOP 代理可以是 JDK 动态代理或者 CGLIB 代理。

织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时完成(例如使用 AspectJ 编译器),也可以在运行时完成。Spring 和其他纯 Java AOP 框架一样,在运行时完成织入。


过滤器与监听器的区别

Filter 可认为是 Servlet 的一种“变种”,它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理,是个典型的处理链。它与 Servlet 的区别在于:它不能直接向用户生成响应。完整的流程是:Filter 对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再对服务器响应进行后处理。 Java 中的 Filter 并不是一个标准的 Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对 HttpServletRequest 进行预处理,也可以对 HttpServletResponse 进行后处理,是个典型的处理链。优点:过滤链的好处是,执行过程中任何时候都可以打断,只要不执行 chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题http://blog.csdn.net/sd0902/article/details/8395641

Servlet,Filter 都是针对 url 之类的,而 Listener 是针对对象的操作的,如 session 的创建,session.setAttribute 的发生,或者在启动服务器的时候将你需要的数据加载到缓存等,在这样的事件发生时做一些事情。http://www.tuicool.com/articles/bmqMjm


请描述一下 java 事件监听机制。

(1) Java 的事件监听机制涉及到三个组件:事件源、事件监听器、事件对象

(2) 当事件源上发生操作时,它将会调用事件监听器的一个方法,并在调用这个方法时,会传递事件对象过来

(3) 事件监听器由开发人员编写,开发人员在事件监听器中,通过事件对象可以拿到事件源,从而对事件源上的操作进行处理。


解释核心容器(应用上下文)模块

这是 Spring 的基本模块,它提供了 Spring 框架的基本功能。BeanFactory 是所有 Spring 应用的核心。Spring 框架是建立在这个模块之上的,这也使得 Spring 成为一个容器。


BeanFactory – BeanFactory 实例

BeanFactory 是工厂模式的一种实现,它使用控制反转将应用的配置和依赖与实际的应用代码分离开来。最常用的 BeanFactory 实现是 XmlBeanFactory 类。

XmlBeanFactory

最常用的就是 org.springframework.beans.factory.xml.XmlBeanFactory,它根据 XML 文件中定义的内容加载 beans。该容器从 XML 文件中读取配置元数据,并用它来创建一个完备的系统或应用。


解释 AOP 模块

AOP 模块用来开发 Spring 应用程序中具有切面性质的部分。该模块的大部分服务由 AOP Aliance 提供,这就保证了 Spring 框架和其他 AOP 框架之间的互操作性。另外,该模块将元数据编程引入到了 Spring。


解释抽象 JDBC 和 DAO 模块

通过使用抽象 JDBC 和 DAO 模块保证了与数据库连接代码的整洁与简单,同时避免了由于未能关闭数据库资源引起的问题。它在多种数据库服务器的错误信息之上提供了一个很重要的异常层。它还利用 Spring 的 AOP 模块为 Spring 应用程序中的对象提供事务管理服务。


解释对象/关系映射集成模块

Spring 通过提供 ORM 模块在 JDBC 的基础上支持对象关系映射工具。这样的支持使得 Spring 可以集成主流的 ORM 框架,包括 Hibernate, JDO, 及 iBATIS SQL Maps。Spring 的事务管理可以同时支持以上某种框架和 JDBC。


解释 web 模块

Spring 的 web 模块建立在应用上下文(application context)模块之上,提供了一个适合基于 web 应用程序的上下文环境。该模块还支持了几个面向 web 的任务,如透明的处理多文件上传请求及将请求参数同业务对象绑定起来。


解释 Spring MVC 模块

Spring 提供 MVC 框架构建 web 应用程序。Spring 可以很轻松的同其他 MVC 框架结合,但 Spring 的 MVC 是个更好的选择,因为它通过控制反转将控制逻辑和业务对象完全分离开来。


ContextLoaderListener 是监听什么事件

ContextLoaderListener 的作用就是启动 Web 容器时,自动装配 ApplicationContext 的配置信息。因为它实现了 ServletContextListener 这个接口,在 web.xml 配置这个监听器,启动容器时,就会默认执行它实现的方法。


Spring IoC 容器

Spring IOC 负责创建对象、管理对象(通过依赖注入)、整合对象、配置对象以及管理这些对象的生命周期。


IOC 有什么优点?

IOC 或依赖注入减少了应用程序的代码量。它使得应用程序的测试很简单,因为在单元测试中不再需要单例或 JNDI 查找机制。简单的实现以及较少的干扰机制使得松耦合得以实现。IOC 容器支持勤性单例及延迟加载服务。


应用上下文是如何实现的?

ClassPathXmlApplicationContext 容器加载 XML 文件中 beans 的定义。XML Bean 配置文件的完整路径必须传递给构造器。 FileSystemXmlApplicationContext 容器也加载 XML 文件中 beans 的定义。注意,你需要正确的设置 CLASSPATH,因为该容器会在 CLASSPATH 中查看 bean 的 XML 配置文件。 WebXmlApplicationContext:该容器加载 xml 文件,这些文件定义了 web 应用中所有的 beans。


有哪些不同类型的 IOC(依赖注入)

接口注入:接口注入的意思是通过接口来实现信息的注入,而其它的类要实现该接口时,就可以实现了注入 构造器依赖注入:构造器依赖注入在容器触发构造器的时候完成,该构造器有一系列的参数,每个参数代表注入的对象。 Setter 方法依赖注入:首先容器会触发一个无参构造函数或无参静态工厂方法实例化对象,之后容器调用 bean 中的 setter 方法完成 Setter 方法依赖注入。

你推荐哪种依赖注入?构造器依赖注入还是 Setter 方法依赖注入?

你可以同时使用两种方式的依赖注入,最好的选择是使用构造器参数实现强制依赖注入,使用 setter 方法实现可选的依赖关系。


什么是 Spring Beans

Spring Beans 是构成 Spring 应用核心的 Java 对象。这些对象由 Spring IOC 容器实例化、组装、管理。这些对象通过容器中配置的元数据创建,例如,使用 XML 文件中定义的创建。 在 Spring 中创建的 beans 都是单例的 beans。在 bean 标签中有一个属性为”singleton”,如果设为 true,该 bean 是单例的,如果设为 false,该 bean 是原型 bean。Singleton 属性默认设置为 true。因此,spring 框架中所有的 bean 都默认为单例 bean。


Spring Bean 中定义了什么内容?

Spring Bean 中定义了所有的配置元数据,这些配置信息告知容器如何创建它,它的生命周期是什么以及它的依赖关系。


如何向 Spring 容器提供配置元数据

有三种方式向 Spring 容器提供元数据: XML 配置文件 基于注解配置 基于 Java 的配置


你如何定义 bean 的作用域

在 Spring 中创建一个 bean 的时候,我们可以声明它的作用域。只需要在 bean 定义的时候通过’scope’属性定义即可。例如,当 Spring 需要产生每次一个新的 bean 实例时,应该声明 bean 的 scope 属性为 prototype。如果每次你希望 Spring 返回一个实例,应该声明 bean 的 scope 属性为 singleton。


Spring 框架中单例 beans 是线程安全的吗?

不是,Spring 框架中的单例 beans 不是线程安全的。


哪些是最重要的 bean 生命周期方法?能重写它们吗?

有两个重要的 bean 生命周期方法。第一个是 setup 方法,该方法在容器加载 bean 的时候被调用。第二个是 teardown 方法,该方法在 bean 从容器中移除的时候调用。 bean 标签有两个重要的属性(init-method 和 destroy-method),你可以通过这两个属性定义自己的初始化方法和析构方法。Spring 也有相应的注解:@PostConstruct 和 @PreDestroy。


什么是 Spring 的内部 bean

当一个 bean 被用作另一个 bean 的属性时,这个 bean 可以被声明为内部 bean。在基于 XML 的配置元数据中,可以通过把元素定义在 或元素内部实现定义内部 bean。内部 bean 总是匿名的并且它们的 scope 总是 prototype。


如何在 Spring 中注入 Java 集合类

Spring 提供如下几种类型的集合配置元素: list 元素用来注入一系列的值,允许有相同的值。 set 元素用来注入一些列的值,不允许有相同的值。 map 用来注入一组”键-值”对,键、值可以是任何类型的。 props 也可以用来注入一组”键-值”对,这里的键、值都字符串类型。


什么是 bean wiring?

Wiring,或者说 bean Wiring 是指 beans 在 Spring 容器中结合在一起的情况。当装配 bean 的时候,Spring 容器需要知道需要哪些 beans 以及如何使用依赖注入将它们结合起来。


什么是 bean 自动装配?

Spring 容器可以自动配置相互协作 beans 之间的关联关系。这意味着 Spring 可以自动配置一个 bean 和其他协作 bean 之间的关系,通过检查 BeanFactory 的内容里没有使用和< property>元素。


解释自动装配的各种模式

自动装配提供五种不同的模式供 Spring 容器用来自动装配 beans 之间的依赖注入: no:默认的方式是不进行自动装配,通过手工设置 ref 属性来进行装配 bean。 byName:通过参数名自动装配,Spring 容器查找 beans 的属性,这些 beans 在 XML 配置文件中被设置为 byName。之后容器试图匹配、装配和该 bean 的属性具有相同名字的 bean。 byType:通过参数的数据类型自动自动装配,Spring 容器查找 beans 的属性,这些 beans 在 XML 配置文件中被设置为 byType。之后容器试图匹配和装配和该 bean 的属性类型一样的 bean。如果有多个 bean 符合条件,则抛出错误。 constructor:这个同 byType 类似,不过是应用于构造函数的参数。如果在 BeanFactory 中不是恰好有一个 bean 与构造函数参数相同类型,则抛出一个严重的错误。 autodetect:如果有默认的构造方法,通过 construct 的方式自动装配,否则使用 byType 的方式自动装配。


自动装配有哪些局限性?

自动装配有如下局限性: 重写:你仍然需要使用 和< property>设置指明依赖,这意味着总要重写自动装配。 原生数据类型:你不能自动装配简单的属性,如原生类型、字符串和类。 模糊特性:自动装配总是没有自定义装配精确,因此,如果可能尽量使用自定义装配。


你可以在 Spring 中注入 null 或空字符串吗

完全可以。


什么是 Spring 基于 Java 的配置?给出一些注解的例子

基于 Java 的配置允许你使用 Java 的注解进行 Spring 的大部分配置而非通过传统的 XML 文件配置。以注解@Configuration 为例,它用来标记类,说明作为 beans 的定义,可以被 Spring IOC 容器使用。另一个例子是@Bean 注解,它表示该方法定义的 Bean 要被注册进 Spring 应用上下文中。


什么是基于注解的容器配置

另外一种替代 XML 配置的方式为基于注解的配置,这种方式通过字节元数据装配组件而非使用尖括号声明。开发人员将直接在类中进行配置,通过注解标记相关的类、方法或字段声明,而不再使用 XML 描述 bean 之间的连线关系。


如何开启注解装配?

注解装配默认情况下在 Spring 容器中是不开启的。如果想要开启基于注解的装配只需在 Spring 配置文件中配置元素即可。


@Required 注解

@Required 表明 bean 的属性必须在配置时设置,可以在 bean 的定义中明确指定也可通过自动装配设置。如果 bean 的属性未设置,则抛出 BeanInitializationException 异常。


@Autowired 注解

@Autowired 注解提供更加精细的控制,包括自动装配在何处完成以及如何完成。它可以像@Required 一样自动装配 setter 方法、构造器、属性或者具有任意名称和/或多个参数的 PN 方法。


@Qualifier 注解

当有多个相同类型的 bean 而只有其中的一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用消除这种混淆,指明需要装配的 bean。 Spring 数据访问


在 Spring 框架中如何更有效的使用 JDBC?

使用 Spring JDBC 框架,资源管理以及错误处理的代价都会减轻。开发人员只需通过 statements 和 queries 语句从数据库中存取数据。Spring 框架中通过使用模板类能更有效的使用 JDBC,也就是所谓的 JdbcTemplate。


JdbcTemplate

JdbcTemplate 类提供了许多方法,为我们与数据库的交互提供了便利。例如,它可以将数据库的数据转化为原生类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据库错误处理功能。


Spring 对 DAO 的支持

Spring 对数据访问对象(DAO)的支持旨在使它可以与数据访问技术(如 JDBC, Hibernate 及 JDO)方便的结合起来工作。这使得我们可以很容易在的不同的持久层技术间切换,编码时也无需担心会抛出特定技术的异常。


使用 Spring 可以通过什么方式访问 Hibernate?

使用 Spring 有两种方式访问 Hibernate: 使用 Hibernate Template 的反转控制以及回调方法 继承 HibernateDAOSupport,并申请一个 AOP 拦截器节点


Spring 支持的 ORM

Spring 支持一下 ORM: Hibernate iBatis JPA (Java -Persistence API) TopLink JDO (Java Data Objects) OJB


如何通过 HibernateDaoSupport 将 Spring 和 Hibernate 结合起来?

使用 Spring 的 SessionFactory 调用 LocalSessionFactory。结合过程分为以下三步: 配置 Hibernate SessionFactory 继承 HibernateDaoSupport 实现一个 DAO 使用 AOP 装载事务支持


Spring 支持的事务管理类型

Spring 支持如下两种方式的事务管理: 编码式事务管理:sping 对编码式事务的支持与 EJB 有很大区别,不像 EJB 与 java 事务 API 耦合在一起.spring 通过回调机制将实际的事务实现从事务性代码中抽象出来.你能够精确控制事务的边界,它们的开始和结束完全取决于你. 声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者 XML 配置管理事务。通过传播行为,隔离级别,回滚规则,事务超时,只读提示来定义.


Spring 框架的事务管理有哪些优点

它为不同的事务 API(如 JTA, JDBC, Hibernate, JPA, 和 JDO)提供了统一的编程模型。 它为编程式事务管理提供了一个简单的 API 而非一系列复杂的事务 API(如 JTA). 它支持声明式事务管理。 它可以和 Spring 的多种数据访问技术很好的融合。


ACID

原子性(Atomic):一个操作要么成功,要么全部不执行.

一致性(Consistent): 一旦事务完成,系统必须确保它所建模业务处于一致的状态

隔离性(Isolated): 事务允许多个用户对相同的数据进行操作,每个用户用户的操作相互隔离互补影响.

持久性(Durable): 一旦事务完成,事务的结果应该持久化.


spring 事务定义的传播规则

PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED–如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与 PROPAGATION_REQUIRED 类似的操作。


spring 事务支持的隔离级别

并发会导致以下问题:

藏读:发生在一个事务读取了另一个事务改写但尚未提交的数据.

不可重复读:在一个事务执行相同的查询两次或两次以上,每次得到的数据不同.

幻读:与不可重复读类似,发生在一个事务读取多行数据,接着另一个并发事务插入一些数据,随后查询中,第一个事务发现多了一些原本不存在的数据.

spring 事务上提供以下的隔离级别:

ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别

ISOLATION_READ_UNCOMMITTED  : 允许读取未提交的数据变更,可能会导致脏读,幻读或不可重复读

ISOLATION_READ_COMMITTD : 允许读取为提交数据,可以阻止脏读,当时幻读或不可重复读仍可能发生

ISOLATION_REPEATABLE_READ: 对统一字段多次读取结果是一致的,除非数据是被本事务自己修改.可以阻止脏读,不可重复读,但幻读可能发生

ISOLATION_SERIALIZABLE : 完全服从 ACID


你更推荐那种类型的事务管理?

许多 Spring 框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理(这种方式允许你通过代码控制业务)。


有几种不同类型的自动代理?

BeanNameAutoProxyCreator:bean 名称自动代理创建器 DefaultAdvisorAutoProxyCreator:默认通知者自动代理创建器 Metadata autoproxying:元数据自动代理


什么是织入?什么是织入应用的不同点?

织入是将切面和其他应用类型或对象连接起来创建一个通知对象的过程。织入可以在编译、加载或运行时完成。


什么是 Spring 的 MVC 框架?

Spring 提供了一个功能齐全的 MVC 框架用于构建 Web 应用程序。Spring 框架可以很容易的和其他的 MVC 框架融合(如 Struts),该框架使用控制反转(IOC)将控制器逻辑和业务对象分离开来。它也允许以声明的方式绑定请求参数到业务对象上。


DispatcherServlet

Spring 的 MVC 框架围绕 DispatcherServlet 来设计的,它用来处理所有的 HTTP 请求和响应。


WebApplicationContext

WebApplicationContext 继承了 ApplicationContext,并添加了一些 web 应用程序需要的功能。和普通的 ApplicationContext 不同,WebApplicationContext 可以用来处理主题样式,它也知道如何找到相应的 servlet。


什么是 Spring MVC 框架的控制器?

控制器提供对应用程序行为的访问,通常通过服务接口实现。控制器解析用户的输入,并将其转换为一个由视图呈现给用户的模型。Spring 通过一种极其抽象的方式实现控制器,它允许用户创建多种类型的控制器。

@Controller annotation

@Controller 注解表示该类扮演控制器的角色。Spring 不需要继承任何控制器基类或应用 Servlet API。

@RequestMapping annotation

@RequestMapping 注解用于将 URL 映射到任何一个类或者一个特定的处理方法上。