spring的概况:spring是一个开源框架,为了解决企业应用开发的复杂性而创建的,但现在不止用于企业应用
spring事业一个轻量级的ioc(控住反转)和aop面向切面 的容器框架。
1:从大小和开销两方面而言Spring都是轻量级的
2:通过控制反转(ioc)技术达到松耦合的目的
3:提供面向切面的编程的丰富支持,允许通过分离应用的业务逻辑于系统级服务进行内聚性的开发区
4:包含并管理应用对象的配置和生命周期,这个意义上是一个容器
5:将简单的组件配置 ,组合成复杂的应用,这个意义上是框架。
spring的结构图:
spring的作用 :
1: 容器
2:提供对多种技术的支持(jms mq UnitTest。。。。。。)
3:Aop(事务管理,日志)
4:提供众多的方便应用的辅助类(JDBC Template)
5:对主流框架良好的支持(hihibernate等)
spring的适用范围
1:构建企业级应用(ssm,ssh)
2:单独使用bean容器(bean的管理)
3:单独使用Aop进行切面管理
4:其他Spring的功能(如对消息的支持)
5:在互联网中的应用。
什么是框架
特点:1半成品
2封装了特定的处理流程和控制逻辑
3成熟的,不断升级改进的软件
框架和类库的区别
1框架一般封装了逻辑,高内聚的,类库则是松散的工具组合。
2框架专注于某一领域,类库更加的通用。
接口
1用于沟通中介物的抽象化
2实体把自己提供给外界的一种抽象化说明,用以由内部操作分离出外部沟通的方法,使其能够被修改内部而不影响外界其他的实体与之与其交互的方式
3对应java接口及声明,声明了哪些方法对外提供.
4在java8中接口拥有方法体
面向接口编程
1结构设计中,分清层次及调用关系。每层只向外(上层)提供一组功能的接口,各层间依赖接口并非实现类
2:接口实现变动不影响各层间的调用,这一点在公共服务中尤为的重要 。
3:面向接口编程中的接口是用于隐藏具体实现和实现多态性的组件
例子:
public interface OneInterface{
String hello(String word);
}
public class OneInterfaceImpl implements OneInterface{
@Overiide
public String hello(String word){
return "OneInterface"+word;
}
public static void main(String[] args){
OneInterfaceImpl one=new OneInterfaceImpl();
System.out.println(one.hello("word"));
}
}
什么是ioc:
控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责依赖和维护的
Di(依赖注入)是一种实现方式
目的:创建对象并组装对象之间的关系
(获得依赖对象的过程被反转了,这个过程由自身管理变成了由Ioc容器主动注入)
spring中bean的配置(两种方式1配置 2注解)、
1:配置方式
<?xml version="1.0" encoding="UTF-8"?>
//版本和编码的声明
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
>
//命名空间
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
//声明一个bean ,id为唯一标识,class对于具体的类
</bean>
</beans>
单元测试
1:下载junit并引入jar包
2:创建UnitTestBean类,完成对Spring配置文件的加载,销毁
3:所有单元测试类都要继承自UnitTestBean类,通过他的getBean方法获取想要得到的对象
4:子类(具体执行单元测试的类)加注解:
@RunWith(BlockJUnit4ClassRunner.class)
5:单元测试的方法加注解:@Test
6:右键选择要执行的单元测试方法执行或执行一个类全部的单元测试方法。
具体的代码:
public class UnitTestBase {
private ClassPathXmlApplicationContext context;
private String springXmlpath;
public UnitTestBase() {}
public UnitTestBase(String springXmlpath) {
this.springXmlpath = springXmlpath;
}
@Before
public void before() {
if (StringUtils.isEmpty(springXmlpath)) {
springXmlpath = "classpath*:spring-*.xml";
}
try {
context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
context.start();
} catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
@SuppressWarnings("unchecked")
protected <T extends Object> T getBean(String beanId) {
try {
return (T)context.getBean(beanId);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
protected <T extends Object> T getBean(Class<T> clazz) {
try {
return context.getBean(clazz);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
}
测试类:
@RunWith(BlockJUnit4ClassRunner.class)
public class TestOneInterface extends UnitTestBase {
public TestOneInterface() {
super("classpath:spring-ioc.xml");
}
@Test
public void testSay() {
OneInterface oneInterface = super.getBean("oneInterface");
oneInterface.say("This is a test.");
}
}
bean容器的初始化过程
基础两个包
-org.springframework.beans
-org.springframework.context
-BeanFactory提供配置结构和基本功能,加载并初始化Bean
-ApplicationContext保存了Bean对象并在spring中被广泛的使用
加载方式-ApplicationContext
-本地文件
-Classpath
-Web应用中依赖servlet或Listener
案例:
1文件:
FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("F:/Spring/src/main/resources/spring-ioc.xml");
2classpath:
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring-ioc.xml");
3web应用
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--2 -->
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextloaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
//有两个类分别为ContextLoaderListener和ContextloaderServlet,都可以加载配置文件。
spring的注入
spring注入是指在启动spring容器加载bean配置的时候,完成对变量的赋值
常用的两种方式
1:设置注入
2:构造注入
设置注入
<bean id="DAO" class="com.atguigu.crud.bean.InjectionDAO">
</bean>
<bean id="ServiceImpl " class="com.atguigu.crud.bean.InjectionServiceImpl ">
<property name="injectionDAO" ref="DAO"/>
</bean>
设置注入会提前调用属性的set的方法,为属性赋值。
构造注入
<bean id="DAO" class="com.atguigu.crud.bean.InjectionDAO">
</bean>
<bean id="ServiceImpl " class="com.atguigu.crud.bean.InjectionServiceImpl ">
<constructor-arg name="injectionDAO" ref="DAO"/>
</bean>
通过调用构造方法进行赋值
代码:
public class InjectionServiceImpl implements InjectionService {
private InjectionDAO injectionDAO;
//构造器注入
public InjectionServiceImpl(InjectionDAO injectionDAO1) {
this.injectionDAO = injectionDAO1;
}
//设值注入
public void setInjectionDAO(InjectionDAO injectionDAO) {
this.injectionDAO = injectionDAO;
}
}
bean的配置项
1:id (唯一标识 )
2:Class(具体类,这个是必须的)
3:Scope(作用域)
4:Constructor argguments(构造器仓鼠)
5:Properties(属性)
6:Autowiring mode(自动装配模式)
7:lazy-initialization mode(懒加载模式)
8:Initalization/destruction method(初始化和销毁的方法)
bean的作用域Scope(五种类型)
1:singleton:单例,指一个bean容器中只存在一份
2:prototype:每次请求(每次使用)创建新的实列,destroy方式不生效
3:request:每次http请求创建一个实列且仅在当前的request内有效
4:session:同上每次http请求创建,当前session内有效
5:global session:基于portlet的web中有效(portlet定义了global session),如果在web中,同session
(如果在单元测试类中用两个测试方法获取同一个id的bean,
会先启动一个ioc容器,关闭后在启动一个,因此如果使用Scope为单例将获得两个不同的bean如下图:)
bean的生命周期
bean的初始化:(两种)
1:实现org.springframework.beans.factory.InitializingBean接口,覆盖afterPropertiesSet方法
2:配置Init-method
bean的销毁:(两种)
1实现org.springframework.beans.factory.DisposableBean接口,覆盖destroy方法
2:配置Destroy-method
配置全局默认初始化,销毁方法(可选,没有方法的话,不会报异常,上面两种必须配置方法)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-init-method="defautInit" default-destroy-method="defaultDestroy">
<bean id="beanLifeCycle" class="com.imooc.lifecycle.BeanLifeCycle" init-method="start" destroy-method="stop"></bean>
</beans>
同时以两种方式创建和初始化bean的时候实现接口优先于配置,当配置了初始化或销毁方法,全局默认将被覆盖
Aware
1:Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化之后,可以获得相应的资源
2:通过Aware接口,可以对Spring相应的资源进行操作(一定要慎重)
3:对Spring进行简单的扩展提供了方便的入口
1 ApplicationContextAware:获取ApplicationContext(上下文路径对象)
2 ApplicationEventPublisherAware
3 BeanClassLoaderAware
4 BeanFactoryAware
5 BeanNameAware:获取BeanName
6 BootstrapContextAware
7 LoadTimeWeaverAware
等等。
bean的自动装配
1:no:不做任何的操作
2:byname: 根据属性名自动装配。此选项将检查容器并根据查找与属性完全一致的bean,并将其与属性自动装配
3:bytype:如果容器中存在一个与指定属性相同的bean,那么将与该属性自动装配;如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用bytype的方式进行自动装配;如果没有找到相应的bean,则什么事情都不会发生
4:Constructor:于bytype的方式类似,不同之处在于它用于构造参数。如果容器没有找到与构造参数类型一致的bean,那么将会抛出异常。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="constructor"//bytype//byname>
<bean id="autoWiringService" class="com.imooc.autowiring.AutoWiringService" ></bean>
<bean class="com.imooc.autowiring.AutoWiringDAO" ></bean>
</beans>
以byname和bytype的方式自动装配的话,被引用的类,声明set方法(寻找和id名一样的bean,bytype和bean的id名无关)
以bytype的方式自动装配的话,被引用的类,声明构造方法
public class AutoWiringService {
private AutoWiringDAO autoWiringDAO;
//Constructor设置构造函数
public AutoWiringService(AutoWiringDAO autoWiringDAO) {
System.out.println("AutoWiringService");
this.autoWiringDAO = autoWiringDAO;
}
//byname设置set方法
public void setAutoWiringDAO(AutoWiringDAO autoWiringDAO) {
System.out.println("setAutoWiringDAO");
this.autoWiringDAO = autoWiringDAO;
}
public void say(String word) {
this.autoWiringDAO.say(word);
}
}
文件获取之Resource
针对于资源文件的统一接口
Resource:
1UrlResource:Url对应的资源,根据一个Url地址即可构建
2ClassPathResource:获取类路径文件下的资源文件
3FileSystemResource:获取文件系统里面的资源文件
4ServletContextResource:ServletContext封装的资源,用于访问ServletContext环境下的资源
5InputStreamResource:针对于输入流封装的资源
6ByteArrayResource:针对于字节数组封装的资源
ResourceLoader(对Resource进行资源加载)
spring中所有的application Context都实现了ResourceLoader接口
输入的路径类型如下图:
代码如下:
public class MoocResource implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
public void resource() throws IOException {
Resource resource = applicationContext.getResource("config.txt"//写路径,没有前缀的时候根据classpath来创建的);
System.out.println(resource.getFilename());
System.out.println(resource.contentLength());
}
}
==================================================================================
方式二注解基于注解方式的ioc容器的管理
从spring3.0开始,spring javaConfig项目提供了很多的特征,包括使用java而不是xml来定义bean。
@Component是一个通用的注解,可以用于任何的bean
@Repository通常用于注解dao类,即持久层
@Service通常用于注解Service类,即服务层
@Controller通常用于注解Controller类,即控制层(mvc)
类的自动检测和注册bean
标签component-scan会扫描基于类和方法的注解
标签annotation-config只会去扫描类中方法和属性的注解(前者包含后者)
type的类型有:
annotation 目标组件中出现在type级别的注释。
assignable 目标组件可分配给(扩展/实现)的类(或接口)(具体的某一个类)。
aspectj 由目标组件匹配的AspectJ类型表达式。
regex 由目标组件类名匹配的正则表达式。
custom :org.springframe .core的自定义实现。TypeFilter接口类型。
没有指定名称(bean的name属性)的话,默认id为类名首字母小写
自定义命名策略需要指定name-genregenerator为我们需要实现接口的类
@Required注解(不常用,了解即可)
1:@Required适用bean属性的set方法
2:这个注解表示,受影响的bean属性必须在配置的时候被填充,通过在bean定义或通过自动装配一个明确的属性值
@Autowired
1可以将 @Autowired注解在set方法上
2@Autowired可以用于构造器或者成员变量
默认情况下,如果找不到合适的bean将会导致@Autowired失败抛出异常,可以通过下面的方式来避免(非必须的,只有在使用的时候发现异常)
注意点:
1每个类只能有一个构造器被标记为Required=true(默认值为false)
2@Autowired的必要属性,建议使用@Required来代替
例子:
public interface BeanInterface {
}
@Order(1)
@Component
public class BeanImplTwo implements BeanInterface {
}
@Order(2)
@Component
public class BeanImplOne implements BeanInterface {
}
测试类
@Component
public class BeanInvoker {
@Autowired
private List<BeanInterface> list;
@Autowired
private Map<String, BeanInterface> map;
@Autowired
@Qualifier("beanImplTwo")
private BeanInterface beanInterface;
public void say() {
if (null != list && 0 != list.size()) {
System.out.println("list...");
for (BeanInterface bean : list) {
System.out.println(bean.getClass().getName());
}
} else {
System.out.println("List<BeanInterface> list is null !!!!!!!!!!");
}
System.out.println();
if (null != map && 0 != map.size()) {
System.out.println("map...");
for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue().getClass().getName());
}
} else {
System.out.println("Map<String, BeanInterface> map is null !!!!!!!!!!");
}
System.out.println();
if (null != beanInterface) {
System.out.println(beanInterface.getClass().getName());
} else {
System.out.println("beanInterface is null...");
}
}
输出结果
@Order只针对list有效,map无效
xml中定义@qualifier
自定义@qualifier
1:
2:
基于java容器的注解@bean
(@Component和@Bean都是用来注册Bean并装配到Spring容器中,但是Bean比Component的自定义性更强。可以实现一些Component实现不了的自定义加载类。)
如果定义在方法上@bean的名称没有指定名称(默认为方法名)
使用@ImportResource和@Value注解进行资源文件的读取
xml加载资源文件
注解加载资源文件:
@Bean和@Scope
proxyMode代理方式
基于泛型的自动装配
自定义注解(了解)
注解@Resource(jsr-250支持)
(方法名和属性名 )
回调初始化和销毁
例子:
@Repository
public class JsrDAO {
public void save() {
System.out.println("JsrDAO invoked.");
}
}
//@Service
@Named
public class JsrServie {
// @Resource
// @Inject
private JsrDAO jsrDAO;
// @Resource
@Inject
public void setJsrDAO(@Named("jsrDAO") JsrDAO jsrDAO) {
this.jsrDAO = jsrDAO;
}
@PostConstruct
public void init() {
System.out.println("JsrServie init.");
}
@PreDestroy
public void destroy() {
System.out.println("JsrServie destroy.");
}
public void save() {
jsrDAO.save();
}
}
执行结果:
@Autowired和@Resource区别:
1、 @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
2、 @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
@Autowired()@Qualifier("baseDao")
privateBaseDao baseDao;
3、@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
@Resource(name="baseDao")
privateBaseDao baseDao;
总结:
@Autowired//默认按type注入
@Qualifier("cusInfoService")//一般作为@Autowired()的修饰用
@Resource(name="cusInfoService")//默认按name注入,可以通过name和type属性进行选择性注入
一般@Autowired和@Qualifier一起用,@Resource单独用。
当然没有冲突的话@Autowired也可以单独用
@Inject注解
3引入jar包
注解在类上于@Component等效
总结来源于慕课网免费课程《spring入门篇》。