Spring框架学习总结
Spring框架的优势是模块化的IoC设计模式,使得开发人员可以专心开发程序的模块化部分。它能够降低开发企业级应用的复杂性,使用Spring替代EJP发开企业级应用,而不用提心工作量太大,开发进度难以控制和复杂的测试过程等问题。Spring简化了企业级应用的开发,降低了开发成本并整合了各种流行框架,它以IoC和AOP(面向切面编程)两种先进的技术为基础,完美简化了企业级应用开发的复杂度。
Spring组成
使用BeanFactory管理Bean
BeanFactory采用了JAVA经典的工厂模式,通过从XML配置文件(applicationContext.xml)或属性文件(.properties)中读取JavaBean的定义来创建,配置和管理JavaBean。BeanFactory有很多实现类,其中XmlBeanFactory可以通过流行的XML文件格式读取配置信息来加载JavaBean。Spring通过BeanFactory对象使用控制反转模式将应用程序的配置和依赖规范与实际的应用程序代码分开,但BeanFactory是Spring低层的实现,在实际开发中一般使用该 接口的子接口ApplicationContext子接口。
第一步: 创建用户的JavaBean
第二步:applicationContext.xml文件配置
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-insance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--配置Service,<bean>配置需要创建的对象,id:用于之后谁用谁从srping容器获得实例时使用的,class:需要创建实例的全限定类名-->
<bean name=“user” class="com.mr.user.User">
<property name="name" >
<value> 无语 </value>
</property >
<property name="age" >
<value> 30 </value>
</property >
<property name="sex" >
<value> 女 </value>
</property >
</bean>
<bean name="/main.do" class="com.mr.main.Manager">
<property name="user"> <!--一看依赖注入采用的是setter注入-->
<ref local="user"/> <!--引用其它JavaBean的实例对象。==local==代表寻找 本xml文件中的name为user的bean,==bean==代表寻找全局中的bean,==parant==:用于指定其依赖的父JavaBean定义-->
</property> //区别下面的写法
</bean>
<bean id="test" calss="com.mr.test.Test"/>
<property name="userSerice" ref="userService"/>
</bean>
</beans>
第三步:加载applicationContext.xml文件
Resource resource = new ClassPathResource(“applicationContext.xml”);//ClassPathResource加载配置文件
BeanFactory factory = new XmlBeanFactory(resource);
Test test = (Test)factory.getBean(“test”);//BeanFactory的getBean()方法获取JavaBean的实例,并且向上转换为需要的接口类型。从而在容器中开始这个JavaBean的全生命周期。
应用ApplicationContext
BeanFactory实现了IoC控制,所以可以称为“IoC容器”,而ApplicationContext扩展了BeanFactory实器,并添加了对I18N(国际化)和生命周期事件的发布监听等更加强大的功能。使之成为Spring中强大的企业级IoC容器,在这个容器中提供了对其它框架和EJB的集成、远程调用、WebService、任务调度和JNDI等企业级服务,在Spring应用中大多采用ApplicationContext容器来开发企业级应用程序。
说明:ApplicationContext不仅仅提供了BeanFactory的所有特性,而且允许使用更多的声明方式来得到所需的功能。
ApplicationContex接口有如下3个实现类。可以实例化其中任何一个类来创建Spring的ApplicationContext容器,把上面低层的两句合并成了一句。
- 1.ClassPathXmlApplicationContext类
该类从当前类路径中检索配置文件并加载来创建容器的实例,其语法格式只需要一句了,如下:ApplicationContext context= new ClassPathXmlApplicationContext(String configLocation);参数configLocation参数用于指定Spring配置文件的名称和位置。
然后就可以通过下面方法来获取对象
context.getBean(“BeanId”);//来拿对象
-
2.FileSystemXmlApplicationContext类
该类不从类路 径中获取配置文件,如果配置文件放在文件系的目录下,而通过参 数指定配置文件的位置,即它可以获取类路径之外的资源,其语法格式如下:
ApplicationContext context= new FileSystemXmlApplicationContext(“com/spark/system/applicationContext.xml”);//如果配置文件放在文件系统的目录下则优先使用该方式
然后就可以通过下面方法来获取对象 ,要注意向上转换为需要的接口类型
UserService userService=(UserService) context.getBean(“BeanId”);//来拿对象
说明: 1,2种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Srping的情况。 -
3.WebApplicationContext类,此类不再用new了区别于上面2个类的地方。
WebApplicationContext是Spring的Web应用容器,在Servlet中使用该类的方法一是在Servlet的web.xml文件中配置Spring的ContextLoderListener监听器。方法二是修改web.xml配置文件,在其中添加一个Servlet,定义使用Spring的org.springframwork.web.context.ContextLoaderServlet 见下面标红部分或org.springframwork.web.servlet.DispatcherServlet类。见下面标红部分。
方法一:这种方法适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后通过它获取需要的类实例。
//获取失败会抛出异常
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
//获取失败会返回Null
ac1.getBean("beanId");
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
ac2.getBean("beanId");
方法二
见微信朋友圈2月22日 spring获取WebApplicationg.getBean多种途径。
Spring IoC
Spring框架中的各个部分充分使用了依赖注入技术,使得代码中不再有单实例垃圾和麻烦的属性文件,取而代之的是一致和优雅的应用程序代码。
- 控制反转与依赖注入
IoC技术将创建实例的任务交给IoC容器,这样在开发应用代码时只需要直接使用类的实例即可,这就是IoC控制反转。
容器通过调用类的构造方法和setter方法为对象属性赋值,并将其所需的依赖关系注入对象中。这就是依赖注入。
说明:由于在控制反转模式下把对象放在XML文件中定,所以开发人员实现一个子类更为简单,即只需修改XML文件即可,而且控制反转颠覆了“在使用对象之前必须创建”的传统概念,开发人员不必再关注类是如何创建的,只需从容器中抓取一个类后直接调用即可。 - 配置Bean
在Spring中无论使用哪种容器,都需要先配置文件中读取JavaBean的定义信息,然后根据定义信息创建JavaBean的实例对象,并注入其依赖的属性。
要在Spring IoC容器中获取一个Bean,首先要在配置文件的《beans》标签中配置一个子标签《bean》,Spring的控制反 转机制会根据《bean》标签的配置来实例化这个Bean实例。
《bean id=“test” class=“com.mr.Test” />其中id属性为Bean的名称:class属性为对应的完整类名,这样通过BeanFactory的容器或强大的企业级IoC容器ApplicationContext的getBean(“test”)方法即可获取该类的实例。 - setter注入
一个简单的JavaBean的最明显规则是一个私有属性对应setter和getter方法,以封装属性。既然JavaBean有setter方法来设备Bean的属性,Spring就会有相应的支持,怎么支持?即在配置文件中的《property>村签中可以为JavaBean的setter方法传递参数,即通过setter方法为对象属性赋值。
例 15.1通过Spring的setter注入为用户JavaBean的属性赋值。
第一步:首先创建用户JavaBean,
public calss User{
private String name;
private String age;
private sex;
public String setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
第二步 在Spring的配置文件applicationContex.xml中配置该JavaBean,关键代码如下:
<bean name=“user” class="com.mr.user.User">
<property name="name" >
<value> 无语 </value>
</property >
<property name="age" >
<value> 30 </value>
</property >
<property name="sex" >
<value> 女 </value>
</property >
</bean>
上面代码中,《value>标签用于为name属性赋值,这是一个普通的赋值标签。直接在成对的《value>标签中放入数值或其它赋值标签,Spring 会把这个标签提供的属性值注入指定的JavaBean中。
第三步 创建名为ManagerServlet的servlet,在其doGet()方法中,首选装载配置文件并获取Bean来创建对象实例,然后通过Bean对象的相应方法getXX()方法获取 并输出用户信息,关键代码如下:采用Spring中强大的企业级IoC容器ApplicationContext,而没有用低层的需要两个语句的IoC容器BeanFactory.
ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Uer user=(User)fcactory.getBean("user");
System.out.printIn("用户姓名---"+user.getName());
System.out.printIn("用户年龄---"+user.getAge());
System.out.printIn("用户性别---"+user.getSex());
- 构造器注入
在类被实例化时,其构造方法被调用并且只能被调用一次,所以构造器常被用于类的初始化操作,《constructor-arg>是《bean>标签的子标签,通过《constructor-arg>标签的《value>子标签可以为构造方法传递参数。
第一步在用户JavaBean中创建构造方法
public class User{
private String name;
private String age;
private String sex;
//构造 方法
public User(String name,Interger age,String sex){
this.name;
this.age;
this.sex;
public void printInfo(){
System.out.printIn("用户姓名---"+user.getName());
}
}
第二步在Spring的配置文件applicationContext.xml中通过《constructor-arg>标签为JavaBean的属性赋值,
<bean name ="user" class="com.mr.user.User" scope="prototype">
<!--scope属性:1.singleton被标识为单例对象,也是默认,2.prototype被标识为多例对象,3.request:对像与request生命周期一样-->
<constructor-arg>
<value>无语</value>
</constructor-arg>
<constructor-arg>
<value>30</value>
</constructor-arg>
<constructor-arg>
<value>女</value>
</constructor-arg>
</bean>
注意:容器通过多个《constructor-arg>标签为构造方法传递参数,如果标签的赋值顺序与构造方法中参数的顺序或类型不同,那么 程序会产生异常,可以使用《constructor-arg>标签的index和type属性解决 此问题。
<constructor-arg name="name",index="1",type="java.lang.Spring">
<value>无训</value>
</constructor-arg>
(1)setter和构造器注入都是属性依赖注入,并且包括手动和注解装配两种,上面为手动装配方下,下面为注解方式。
- 基于注解:
注解就是一个类,使用@注解名称,开发中使用注解取代XML配置文件,在applicationContext.xml中书写指定扫描注解
<context:compont-scan base-package=”指定扫描x包下所有类的注解“></context:compont-scan>
第一步.类注解@component 取代《bean class = “”>
@component(“id”)取代 《bean id=“” class=“”>
web开发,提供3个@component注解衍生注解(功能一样)
@Repository应用在dao层
@Service 应用在service层
@Controller 应用在web层
说明:类注解@Component注解表明一个类会作为组件类,并告知Spring要为这个类创建bean。
方法返回注解@Bean注解告诉Spring这个用@Bean注解的方法将会返回一个对象。
两者的目的是一样的,都是注册bean到Spring容器中。
区别:
@Component(@Controller、@Service、@Repository)通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中。而@Bean注解通常是我们在标有该注解的方法中定义产生这个bean的逻辑,然后法将会返回一个Bean对象。
即:@Component 作用于类,@Bean作用于方法。
第二步 依赖注入 ,给私有字段设值,也可以给setter方法设值
普通值:@Value(" ")
引用值:方式1:安照类型注入,@Autowired //自动装配,问题:如果匹配多个类型一致的对象,将无法先择注入哪个对象。
方式2:按照名称注入 @AutoWired @Qualifier(“名称teacher”)//@Qualifier(“名称teacher”)告诉Spring容器自动装配哪个名称的对象。
方式3:按照名称注入,@Resource(“名称name=teacher”)//手动注入,指定注入哪个名称的对象。
-
生命周期:
初始化:@PostConstruct //在对象被创建后调用
销毁:@PreDestroy //在销毁之前调用 -
作用域:
@Scope(“prototype”) 多例
注解使用前提,添加命名空间,让Spring扫描含有注解类
<beans xmlns=
<context:component-scan base-package =“com.itheima.g_annotation.a_ioc”></context:component-scan>
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages="com.woniuxy.ssm.mapper")
@ComponentScan(basePackages="com.woniuxy.ssm.service.impl")
@PropertySource("classpath:jdbc.properties")
public class App {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource=new DriverManagerDataSource();
dataSource.