部队网站建设招标,二级域名注册平台,珠海今天最新通知,网站的欢迎页怎么做Spring
Spring是一个开源框架#xff0c;Spring是于2003 年兴起的一个轻量级的Java 开发框架#xff0c;由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之…Spring
Spring是一个开源框架Spring是于2003 年兴起的一个轻量级的Java 开发框架由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构分层架构允许使用者选择使用哪一个组件同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言任何Java应用都可以从Spring中受益。Spring的核心是控制反转IoC和面向切面AOP。简单来说Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
Spring核心
1.控制反转(IOC) 2.面向切面(AOP)
Spring优点
1.解耦, 简化开发: Spring就是一个工厂,可以将所有对象创建和依赖关系维护交给Spring处理 2.AOP支持: 方便实现事务处理, 权限处理, 监控操作 3.声明式事务支持: 只需通过配置就可以完成事务管理 4.提供Junit支持 5.集成其他框架 6.对JavaEE API的封装, 降低开发难度
Spring体系结构
Spring是一个分层架构, 包含的功能可分为大约20个模块.
Core Container(核心容器):Beans: 管理BeansCore: Spring核心Context: 配置文件ExpressionLanguage: SpEL表达式
AOP(切面编程)
AOP框架: Aspects
Data Access(数据库整合):JDBC, ORM, OXM, JMS, Transaction
Web(MVC Web开发):Web, Servlet, Portlet, Struts
Test(Junit整合)IOC(控制反转)
IOC(控制反转): 将创建对象实例交给Spring处理, 每次从Spring工厂中获得对象 下面使用一个简单的例子说明:
目标类:
public interface UserService{void addUser();
}
public class UserServiceImpl implements UserService {public void addUser() {System.out.println(ico add user);}
}Spring的配置文件: 配置文件名, 放置的位置都是任意的, 一般将配置文件命名为applicationContext.xml, 放置在src下
src目录下的applicationContext.xml
?xml version1.0 encodingUTF-8?
!--xsd约束--
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
!--id: Spring帮你new 的那个对象名class: 那个对象的全类名
--
bean iduserService classcom.a_ioc.UserServiceImpl/bean
/beans测试代码:
public class TestIoc {Testpublic void f1(){//XMLPATH代表配置文件所在的位置String XMLPATHapplicationContext.xml;//使用ClassPathXMLApplicationContext(String path)加载指定位置的配置文件ApplicationContext applicationContext new ClassPathXmlApplicationContext(XMLPATH);//使用applicationContext的getBean获得配置文件中id为userService的对象UserService userService (UserService) applicationContext.getBean(userService);userService.addUser();}
}测试方法中不再使用new的方式获得对象, 而是通过控制反转, 将new的行为交给Spring处理(反射机制)
DI(依赖注入)
DI依赖注入: 对实例对象的属性赋值, 一般通过set方法进行反射赋值. 对象的属性一般指另一个对象(就有依赖一说) 下面使用例子说明DI
User的Service层:
public interface UserService{void addUser();
}public class UserServiceImpl implements UserService {//对UserDao对象做依赖注入, 在后面生成get/set方法private UserDao userDao;public void addUser() {userDao.save();}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao userDao;}
}User的Dao层:
public interface UserDao {void save();
}public class UserDaoImpl implements UserDao {public void save() {System.out.println(di save);}
}applicationContext.xml:
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!--property标签用于依赖注入:将ref映射的对象注入到name中name:需要注入的属性名ref:映射到UserDao对象
--bean iduserService classcom.b_di.UserServiceImplproperty nameuserDao refuserDao/property/beanbean iduserDao classcom.b_di.UserDaoImpl/bean
/beans测试: 测试中代码与前面一样几乎不变, 对象的生成, 对象属性的赋值都交给Spring处理, 高度解耦
public class TestDi {Testpublic void f1(){String XMLPATHapplicationContext.xml;ApplicationContext applicationContext new ClassPathXmlApplicationContext(XMLPATH);UserService userService (UserService) applicationContext.getBean(userService);userService.addUser();}
}Spring核心API 顶级接口: BeanFactory用于生成任意的Bean, 采取延迟加载策略, 使用getBean才会初始化BeanBeanFactory子接口: ApplicationContext功能加强, 使用该接口, 当配置文件被加载的时候, 就进行对象实例化ApplicationContext子接口:1.ClassPathXmlApplicationContext用于加载src下的xml运行时, xml在/WEB-INF/classes/...xml2.FileSystemXmlApplicationContext加载指定盘符下的xml运行时, xml在/WEB-INF/...xml 举例说明BeanFactory
public class TestBeanFactory {Testpublic void f1(){String XMLPATHapplicationContext.xml;//加载完配置文件后, 并不会实例化BeanFactory applicationContext new XmlBeanFactory(new ClassPathResource(XMLPATH));UserService userService (UserService) applicationContext.getBean(userService);userService.addUser();}
}调用ClassPathXmlApplicationContext(XMLPATH)加载配置文件, Spring就会调用配置文件中的配置的bean的构造函数, 而XMLBeanFactory(Resource)不会, 只是单纯加载配置文件, 只有当getBean才会调用构造函数
基于XML装配Bean
3种Bean实例化方式: 默认构造获得Bean, 使用静态工厂获得Bean, 使用实例工厂获得Bean
使用默认构造函数:
使用如下标签配置Bean
bean id... class.../bean
注: 该Bean必须有默认构造函数(使用默认构造进行反射生成)静态工厂:
bean id class工厂全类名 factory-method静态方法/bean举例说明:
静态工厂:public class StaticBeanFactory {public static UserService newUserService(){return new UserServiceImpl();}}
测试静态工厂:
public class TestStaticFactory {Testpublic void f1(){String XMLPATHapplicationContext.xml;ApplicationContext applicationContext new ClassPathXmlApplicationContext(XMLPATH);UserService userService (UserService) applicationContext.getBean(userService1, UserService.class);userService.addUser();}
}application.xml:bean iduserService1 classcom.c_createBean.StaticBeanFactory factory-methodnewUserService/bean实例工厂: 先获得工厂的实例对象, 然后通过实例对象创建想要的对象, 实例工厂提供的方法都是非静态方法
实例工厂:
public class MyBeanFactory {public UserService newUserService(){System.out.println(MyBeanFactory newUserService);return new UserServiceImpl();}
}测试方法:
Testpublic void f1(){String XMLPATHapplicationContext.xml;ApplicationContext applicationContext new ClassPathXmlApplicationContext(XMLPATH);UserService userService (UserService) applicationContext.getBean(userService2, UserService.class);userService.addUser();}applicationContext.xml:
!--获得工厂实例--
bean idmyBeanFactory classcom.c_createBean.MyBeanFactory/bean
!--通过工厂实例调用方法获得指定对象--
bean iduserService2 factory-beanmyBeanFactory factory-methodnewUserService/beanSpring中Bean种类
普通Bean: Spring直接创建实例bean id普通Bean名 class普通Bean/beanFactoryBean: 生产特定Bean的工厂,可以是静态/非静态工厂
非静态举例bean id工厂对象名 class工厂类/beanbean id特定Bean factory-bean工厂对象名 factory-method工厂方法名BeanFactory: 使用动态代理生成任意的BeanBean作用域
确定Spring创建Bean实例个数, 在bean标签中使用scope属性确定
singleton(默认值):在Spring中只存在一个Bean实例, 单例模式.
prototype:getBean()的时候都会new Bean(), 多例
request:每次http请求都会创建一个Bean, 仅用于WebApplicationContext环境
session:同一个http session共享一个Bean, 不同Session使用不同的Bean, 使用环境同上
globalSession:用于Portlet, 环境同上bean id... class... scope.../beanSpring生命周期
生命周期详情:
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
5.如果存在类实现 BeanPostProcessor后处理Bean 执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用bean init-methodinit 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor处理Bean 执行postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用bean destroy-methodcustomerDestroy 指定销毁方法 customerDestroy初始化与销毁 在构造方法前-初始化, 容器关闭时-销毁
bean标签写法:
bean id... class... init-method初始化方法名 destory-method销毁方法名
实现初始化与销毁必须满足:容器必须close, 此时销毁方法执行必须是单例下面使用一个简单例子演示:
applicationContext.xml:bean iduserService classcom.e_lifeCycle.UserServiceImpl init-methodmyInit destroy-methodmyDestory/beanUserServiceImp.java:
public class UserServiceImpl implements UserService {public void addUser() {System.out.println(lifeCycle add User);}public void myInit() {System.out.println(init);}public void myDestory() {System.out.println(destory);}
}Test:Testpublic void f1(){String XMLPATHcom/e_lifeCycle/applicationContext.xml;ClassPathXmlApplicationContext applicationContext new ClassPathXmlApplicationContext(XMLPATH);UserService userService (UserService) applicationContext.getBean(userService);userService.addUser();//ApplicationContext没有close方法, 使用ClassPathXmlApplicationapplicationContext.close();}
//在执行构造完Bean对象的时候执行myInit
//在容器关闭之前执行myDestoryBeanPostProcessor实现AOP, 完成事务处理 Bean实现BeanPostProcessor, 当Spring管理Bean的时候, 就能在初始化方法前执行PostProcessAfterInitialization(Object bean, String beanName); 在初始化方法后执行PostProcessBeforeInitialization(Object bean, String beanName);
下面举例说明:
编写BeanPostProcessor:
public class PostProcessor implements BeanPostProcessor{/*** 执行方法之前调用, 就意味着在初始化的时候就会调用事务处理* 此时的事务处理是针对接口中有的方法*/Overridepublic Object postProcessBeforeInitialization(final Object bean, String beanName)throws BeansException {System.out.println(方法前beanName);return bean;}Overridepublic Object postProcessAfterInitialization(final Object bean, String beanName)throws BeansException {System.out.println(方法后beanName);return Proxy.newProxyInstance(PostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {//反射重写invoke, 实现AOPOverridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println(开启事务);Object objectInvoke method.invoke(bean, args);System.out.println(关闭事务);return objectInvoke;}});}
}在applicationContext.xml中配置:
bean classcom.e_lifeCycle.PostProcessor/bean
注册自定义的BeanPostProcessor测试类:
测试类就是前面的初始化与销毁代码
运行结果:构造方法前userServiceinit方法后userService开启事务lifeCycle add User关闭事务destory生命周期, 事件执行流程
使用上面的lifeCycle作为例子
1.加载配置文件, 构造方法执行
2 装载属性调用setter方法
3.通过BeanNameAware接口获得配置文件id属性的内容lifeUser
4.通过ApplicationContextAware接口获得Spring容器
5. 实现BeanPostProcessor后处理初始化前执行postProcessBeforeInitialization方法
6.通过InitializingBean确定属性设置完成之后执行
7.配置init-method执行自定义初始化方法
8. 实现BeanPostProcessor后处理在自定义初始化之后执行postProcessAfterInitialization方法
9.通过DisposableBean接口不需要配置的销毁方法
10.配置destroy-method执行自定义销毁方法属性依赖注入
1.通过构造方法进行装配: 在bean标签中添加constructor-arg标签进行装配. 例如:
bean id... class...constructor-arg nameusername valuejack/constructor-argconstructor-arg index0 typejava.lang.String valuejack/constructor-argconstructor-arg nameusername refuserService/constructor-arg
/beanname: 构造函数的参数名称
value: 为属性注入普通类型数据
index: 构造函数第几个参数
type: 构造函数参数的类型, 结合index使用
ref: 为属性注入其他Bean注: 使用这个参数每次都是调用Bean中首次与标签中数据匹配合适构造函数
2.使用setter方法注入: 就是使用property标签指定name, value/ref值
bean id... class...property nameusername valuejack/property
/beanP命名空间 主要对setter方法依赖注入做简化, 替换property. 在添加P命名空间: 在beans标签中添加: xmlns:p“http://www.springframework.org/shema/p”
将原来的:bean id... class...property nameusername valuejack/property/bean
变为:bean id... class... p:nameusername p:valuejack/beanSPEL 用于简化property中属性名, 与属性值的写法, 类似于EL表达式
property name属性名 value#{表达式}/property
#{123}, #{jack} 代表数字, 字符串
#{beanId} 另一Bean的引用
#{beanId.propertyName} 使用另一个beanId的属性值为当前bean的属性值赋值
#{beanId.clone()} 使用beanId的方法为bean属性赋值
#{T().字段|方法} 使用其他类的字段或方法为bean赋值例:
property namecname value#{jack}/property
property namecname value#{customerId.cname.toUpperCase()}/property通过另一个bean获得属性调用的方法
property namecname value#{customerId.cname?.toUpperCase()}/property
?. 代表: 如果对象不为null将调用方法4.集合注入: 在property标签中注入集合数据
注入数组:
property name属性名arrayvalueA/valuevalueB/valuevalueC/value/array
/property注入List/Set只需将array改为list, set注入Map:
property name属性名mapentry key1 valueA/entryentrykeyvalue2/value/keyvalueB/value/entry上面这两种写法效果一样/map
/property注入Properties数据:
property namepropsDatapropsprop key1A/propprop key2B/prop/props
/property基于注解装配Bean
使用注解的前提:
在 beans 标签下添加 context:component-scan标签, 扫描包下所有类的注解
context:component-scan base-packagecom.itheima.g_annotation.a_ioc/context:component-scan取代 bean 标签的注解:
1. Component(beanId)等价于bean idbeanId class...Component(userServiceId)public Class UserServiceImpl implements UserService{//.............. }2. 在web中, 提供3个注解用于标识三层架构, 这3个注解效果与Component一样Repository: dao层Service: service层Controller: web层取代setter依赖注入的注解: 在类中对象的属性上加注解, 就能完成注入(没有setter方法也可以注入)
1.普通数据类型值: Value(属性值)Valueprivate UserService userService;2.引用数据类型值: 按照类型注入: AutowiredAutowiredprivate UserService userService;按照名称注入: AutowiredQualifier(...) 或者 Resource(...) 两注解效果一样//使用service层生成的userService对象进行注入AutowiredQualifier(userService)private UserService userService;3.生命周期: 配置init-method, destroy-method属性初始化:PostConstructPostConstructpublic void myInit(){......}销毁: PreDestroyPreDestroypublic void myDestroy(){......}4.作用域: 配置scope属性Scope(prototype)配置多例上面有错, 还请指出, 如果认为我写的还不错, 还请点个赞, 多多支持一下, O(∩_∩)O~~