同步操作将从 Java精选/Ebooks 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
1)作用对象不同。@Component注解作用于类,而@Bean注解作用于方法。
2)@Component注解一般是通过类路径扫描来自动侦测及自动装配到Spring容器中,定义要扫描的路径可以使用@ComponentScan注解。@Bean注解一般是在标有该注解的方法中定义产生这个bean,通知Spring这是某个类的实例。
3)@Bean注解相比较@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来完成注册bean。比如引用第三方库的类装配到Spring容器的时候,只能通过@Bean注解来实现。
使用@Bean注解示例:
@Configuration
public class SpringConfig {
@Bean
public IUserService iUserService() {
return new UserServiceImpl();
}
}
上述代码等同于XML配置:
<beans>
<bean id="iUserService" class="com.yoodb.UserServiceImpl"/>
</beans>
使用@Component注解示例:
@Component("iUserService")
public class IUserService implements UserServiceImpl {
}
1)在启动类上添加@EnableScheduling注解,用于开启对定时任务的支持。
2)在需要定时任务的类上添加@Component注解,用于把普通pojo实例化到Spring容器,等同于添加到配置文件中。
3)在方法上添加@Scheduled(cron = "秒分时日月?")注解,用于声明需要执行的定时任务。
实例代码如下:
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
@Configurable
@EnableScheduling
public class ScheduledTasks {
//每10秒执行一次
@Scheduled(fixedRate = 1000 * 10)
public void reportCurrentTime(){
System.out.println ("Scheduling Tasks Examples: The time is now " + dateFormat ().format (new Date ()));
}
//在固定时间执行
@Scheduled(cron = "0 */1 * * * * ")
public void reportCurrentByCron(){
System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date()));
}
private SimpleDateFormat dateFormat(){
return new SimpleDateFormat ("HH:mm:ss");
}
}
1、zone表示执行时间的时区
2、fixedDelay 和fixedDelayString 一个固定延迟时间执行,上个任务完成后,延迟多久执行
3、fixedRate 和fixedRateString一个固定频率执行,上个任务开始后多长时间后开始执行
4、initialDelay 和initialDelayString表示一个初始延迟时间,第一次被调用前延迟的时间
5、cron是设置定时执行的表达式,如0 0/1 * * * ?每隔一分钟执行一次。
cron参数说明:
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 12 ? * WED 表示每个星期三中午12点 0 0 12 * * ? 每天中午12点触发
按顺序依次为:
秒(0
59) 分钟(059) 小时(023) 天(月)(031,但是需要考虑月的天数) 月(011) 天(星期)(17 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT) 年份(1970至2099)
在Spring中定义一个时,我们也可以为bean声明一个范围。它可以通过bean定义中的scope属性定义。
例如,当Spring每次需要生成一个新的bean实例时,bean的scope属性就是原型。另一方面,当每次需要Spring都必须返回相同的bean实例时,bean的scope属性必须设置为singleton。
注:bean的scope属性有prototype,singleton,request, session几个属性
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。
1、BeanFactory是Spring里面最底层的接口,是IoC的核心,定义了IoC的基本功能,包含了各种Bean的定义、加载、实例化,依赖注入和生命周期管理。
ApplicationContext接口作为BeanFactory的子类,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
1)继承MessageSource,因此支持国际化。
2)资源文件访问,如URL和文件(ResourceLoader)。
3)载入多个(有继承关系)上下文(即同时加载多个配置文件) ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
4)提供在监听器中注册bean的事件。
2、BeanFactroy采用的是延迟加载形式来注入Bean的,只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能提前发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
ApplicationContext是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。
ApplicationContext启动后预载入所有的单实例Bean,所以在运行的时候速度比较快,因为它们已经创建好了。相对于BeanFactory,ApplicationContext 唯一的不足是占用内存空间,当应用程序配置Bean较多时,程序启动较慢。
3、BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是BeanFactory需要手动注册,而ApplicationContext则是自动注册。
4、BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。
装配或bean装配是指在Spring容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。
Spring中单例bean默认是线程安全的,前提是这个对象没有非静态成员变量。
Spring中单例bean是存在线程安全是因为多个线程操作同一个对象时,这个对象非静态成员变量的写操作会存在线程安全问题。
两种常见的解决方案:
1)bean对象中尽量避免定义可变的成员变量。
2)推荐在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中。
3)设置scope="prototype"参数。
1、IOC控制反转
传统资源查找方式是要求组件向容器发起请求,查找资源作为回应,容器适时返回资源;而IOC查找方式是容器会主动将资源提供给它所管理的组件,组件只需要选择一个合适的方式来接收资源,也被称为查找的被动式。
创建对象实例的控制权从代码控制剥离到IOC容器控制(之前的写法由程序代码直接操控使用new关键字),实际就是在xml文件控制,控制权的转移是所谓反转,侧重于原理。
2、DI依赖注入
DI依赖注入可以理解成IOC的另一种表达方式是组件以一些预先定义好的方式(如:setter方法)接收来自容器的资源注入;相对于IOC而言,这种表述更加直接。创建对象实例时,为这个对象注入属性值或其它对象实例,侧重于实现。
属性注入(最常用)
1)通过set方法注入Bean的属性值或依赖的对象。
2)name属性:制定Bean属性set方法后的属性名。
3)value属性值:可以使(value)子节点指定属性值。
构造器注入
1)通过构造器注入Bean属性值或依赖对象,它保证Bean实例在实例化后可以使用。
2)构造器注入在一样。
3、区别
1)IOC和DI是Spring核心思想的不同方面的描述。
2)依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。
3)依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
流行的「Martin Fowler将IoC改名为DI」的说法,Martin Fowler的原文在这里:
Inversion of Control Containers and the Dependency Injection pattern As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.
大意翻译:
已经存在某种模式,该模式被称为IoC,但IoC太普遍,任何框架都IoC,为了让表意更明确,决定用DI来精确指称那个模式。
可以理解成:
IoC ioc = the_pattern;
DI di = (DI)ioc;
连接点(Joint Point)
连接点是指一个应用执行过程中能够插入一个切面的点,可以理解成一个方法的执行或者一个异常的处理等。
连接点可以是调用方法、抛出异常、修改字段等时,切面代码可以利用这些点插入到应用的正规流程中。使得程序执行过程中能够应用通知的所有点。
在Spring AOP中一个连接点总是代表一个方法执行。如果在这些方法上使用横切的话,所有定义在EmpoyeeManager接口中的方法都可以被认为是一个连接点。
切入点(Point cut)
切入点是一个匹配连接点的断言或者表达式,如果通知定义了“什么”和“何时”,那么切点就定义了“何处”。
通知(Advice)与切入点表达式相关联,切入点用于准确定位,确定在什么地方应用切面通知。
例如表达式
execution(* EmployeeManager.getEmployeeById(...))
可以匹配EmployeeManager接口的getEmployeeById()。
Spring默认使用AspectJ切入点表达式,由切入点表达式匹配的连接点概念是AOP的核心。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。