1、spring是什么?它包括哪几个部分?
Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。
2、什么是IoC?
1)专业术语
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。
2)释义
Spring提出了对象工厂的概念,由Spring工厂来管理对象的生命周期。所谓对象生命周期指的是从对象的创建一直到对象的销毁都由Spring来管理。我们无需再自己new对象,而是从Spring工厂中获取需要的对象。甚至对象的依赖也由工厂来注入,无需手动注入依赖。
3、什么是DI?
Dependency Injection:依赖注入。它是 spring 框架核心 ioc 的具体实现。 我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
4、@Configuration 、@ComponentScan、@Bean、@Import 注解有什么作用?
@Configuration:
用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。
@ComponentScan:
用于指定 spring 在初始化容器时要扫描的包。
@Bean:
该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
@Import:
用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。
@Configuration
@ComponentScan("com.czxy")
@Import({ JdbcConfig.class})
public class SpringConfiguration {
}
5、如何使用注解加载properties配置文件?
@PropertySource:
用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到 properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
jdbc.properties 文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/day44\_ee247\_spring
jdbc.username=root
jdbc.password=1234
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig{
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
\* 创建一个数据源,并存入 spring 容器中
\* @return
*/
@Bean(name="dataSource")
public DataSource createDataSource() {
try {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
return ds;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
##6、创建bean的注解有哪些?
注解 | 描述 |
---|---|
@Component | 将修饰的资源交予spring管理。 value属性:为资源命名(唯一标识) |
@Controller | 衍生注解,与@Component作用和属性相同。特用于修饰表示层的资源。 |
@Service | 衍生注解,与@Component作用和属性相同。特用于修饰业务逻辑层的资源。 |
@Repository | 衍生注解,与@Component作用和属性相同。特用于修饰数据访问层的资源。 |
7、依赖注入的注解有哪些?
注解 | 描述 | 修饰位置 |
---|---|---|
@Resource(name=”…”) | 按照指定名称注入对象 | 字段、setter方法 |
@ Resource | 按照类型注入对象 | 字段、setter方法 |
@Value | 注入简单值 | 字段、setter方法、参数 |
@PropertySource | 加载properties配置文件 | 类 |
@Autowired | 自动按照类型注入。 | 字段 |
@Qualifier | 在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。 | 字段 |
@Autowired注意事项:
当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型。当有多个 类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到 就报错。
@Qualifier注意事项:
在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和 @Autowire 一起使用;但是给方法参数注入时,可以独立使用。
1)普通数据注入
示例:字符串类型的成员变量和方法参数注入数据.
public class SpringConfigruation {
@Value("com.mysql.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://127.0.0.1:3306/crm\_ssm\_v1_0")
public void setUrl(String url){
System.out.println("字段:" + driver);
System.out.println("方法:" + url);
}
}
2) properties数据注入
示例:
package com.czxy.demo02;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@Configuration
@PropertySource("classpath:db.properties")
public class SpringConfig02 {
// 在4.2.4版本读取properties必须写,必须要写的固定格式
@Bean
public static PropertySourcesPlaceholderConfigurer create(){
return new PropertySourcesPlaceholderConfigurer();
}
}
注意事项:
-
@PropertySource加载properties配置文件,“classpath:”固定前缀,表示从类路径下加载配置文件。
-
@Value(${jdbc.driver}) 获得配置文件中指定key的内容。
-
必须配置PropertySourcesPlaceholderConfigurer实例。
8、什么是AOP?
AOP:全称是Aspect Oriented Programming即:面向切面编程。
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用代理的技术,在不修改原来代码的基础上,对已有方法进行增强。
9、AOP相关术语有哪些?
Joinpoint( 连接点): 所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。 Pointcut( 切入点): 所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
Advice( 通知/ 增强): 所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。 通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。 Introduction( 引介): 引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。 Target( 目标对象):代理的目标对象。 Weaving( 织入):是指把增强应用到目标对象来创建新的代理对象的过程。 spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。 Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类。 Aspect( 切面):是切入点和通知(引介)的结合。
10、AOP的相关注解有哪些?
注解 | 描述 |
---|---|
@Aspect | 把当前类声明成切面类 |
@Before | 把当前方法看成是前置通知 |
@AfterReturning | 把当前方法看成是后置通知。 |
@AfterThrowing | 把当前方法看成是异常通知 |
@After | 把当前方法看成是最终通知 |
@Around | 把当前方法看成是环绕通知 |
@Pointcut | 指定切入点表达式 |
11、切入点表达式的注意事项有哪些?
12、aop的实现方式
需求: 使用AOP 对UserService接口的两个方法进行增强. 在方法执行之前,开启事务,在方法执行之后关闭事务.
第一步: Pom中需要添加aop相关的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${org.springframework.version}</version>
</dependency>
第二步:目标类实现
//
public interface UserService {
public void addUser();
public void delUser();
}
@Service
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("添加用户 ");
}
@Override
public void delUser() {
System.out.println("删除用户");
}
}
第三步:切面类实现
@Component
@Aspect
public class MyAspact02 {
@Before("execution(public void com.czxy.demo02.UserService.*())")
public void bf(){
System.out.println("开启事务");
}
@After("execution(public void com.czxy.demo02.UserService.*())")
public void af(){
System.out.println("关闭事务");
}
}
第四步:配置类实现
@Configuration
@ComponentScan(basePackages = "com.czxy.demo02")
@EnableAspectJAutoProxy
public class SpringConfiguration2 {
}
第五步:测试类实现
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration2.class)
public class TestB {
@Resource
private UserService userService;
@Test
public void test01(){
userService.addUser();
System.out.println("----------");
userService.delUser();
}
}
13、如何启用事务?
@ComponentScan(basePackages={"com.czxy"})
@PropertySource("classpath:jdbc.properties") //加载配置文件
@EnableTransactionManagement
public class SpringConfigruation {
//解析 ${jdbc.driver} 在 4.2.4中必须配置内容
@Bean
public static PropertySourcesPlaceholderConfigurer configurer(){
return new PropertySourcesPlaceholderConfigurer();
}
/**
\* 获得数据
*/
@Value("${jdbc.driver}")
private String driverClass;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
\* 配置数据源
\* @return
*/
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
/**
\* 事务管理器
\* @param dataSource
\* @return
*/
@Bean
public DataSourceTransactionManager txManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}
14、ACID特性是什么?
原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
15、事务的隔离级别有哪些?
Read uncommitted:读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。
Read committed:读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。
Repeatable read:重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。(不可重复读对应的是修改,即UPDATE操作)
Serializable:是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。
16、pom附录
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>