1.Spring
是什么
Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,它以IOC控制反转和AOP面向切面编程为核心,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术;还有个强大之处就是可以整合众多的第三方开源框架和类库,所以逐渐成为使用最多的 Java EE 企业级应用的开源框架。
特点
(1)方便解耦,简化开发 (2)Aop 编程支持 (3)方便程序测试 (4)方便和其他框架进行整合 (5)方便进行事务操作 (6)降低 API 开发难度
优势
1、非侵入式设计 Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。 2、方便解耦、简化开发 Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器的管理,大大的降低了组件之间的耦合性。 3、支持AOP Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性。 4、支持声明式事务处理 只需要通过配置就可以完成对事物的管理,而无须手动编程。 5、方便程序的测试 Spring提供了对Junit4的支持,可以通过注解方便的测试Spring程序。 6、方便集成各种优秀框架 Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如Struts、Hibernate、MyBatis、Quartz等)的直接支持。 7、降低Jave EE API的使用难度。 Spring对Java EE开发中非常难用的一些API(如JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。
2.耦合是什么意思
1.什么是耦合 程序间的依赖关系 包含了类之间的依赖和方法的依赖 2.什么叫解耦 降低程序间的依赖 开发中,要做到:编译期不依赖,运行期依赖
3.Spring核心是什么
Spring 有两个核心部分:IOC 和 Aop (1)IOC:控制反转,把创建对象过程交给 Spring 进行管理 (2)Aop:面向切面,不修改源代码进行功能增强
4.IOC什么含义
(1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理 (2)使用 IOC 目的:为了耦合度降低 IOC 底层原理 (1)xml 解析、工厂模式、反射 1、IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂 2、Spring 提供 IOC 容器实现两种方式:(两个接口) (1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
- 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人 员进行使用 - 加载配置文件时候就会把在配置文件对象进行创建
3、ApplicationContext 接口有实现类
5.DI是什么 和IOC有什么区别
所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周期的管理,而是在需要时由Spring框架提供,这个由spring框架管理对象创建和生命周期的机制称之为控制反转。而在 创建对象的过程中Spring可以依据配置对对象的属性进行设置,这个过程之为依赖注入,也即DI。 在初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到其中的标签时,会根据该标签中的class属性指定的类的全路径名,通过反射创建该类的对象,并将该对象存入内置的Map中管理。其中键就是该标签的id值,值就是该对象。
之后,当通过getBean方法来从容器中获取对象时,其实就是根据传入的条件在内置的Map中寻找是否有匹配的键值,如果有则将该键值对中保存的对象返回,如果没有匹配到则抛出异常。
由此可以推测而知:
默认情况下,多次获取同一个id的bean,得到的将是同一个对象。
不可以配置多个id相同的bean
可以配置多个id不同但class相同的bean
6.属性注入的方式
1.set方法注入属性 创建类,定义属性和对应的 set 方法
public class Book {
private String bname;
private String bauthor;
private String address;
//set方法注入
public void setBauthor(String bauthor) {
this.bauthor = bauthor;
}
public void setBname(String bname) {
this.bname = bname;
}
}
在 spring 配置文件配置对象创建,配置属性注入
<bean id="book" class="spring5.Book">
<!--使用 property 完成属性注入
name:类里面属性名称
value:向属性注入的值
-->
<property name="bname" value="java"></property>
<property name="bauthor" value="js"></property>
</bean>
2.使用有参数构造进行注入 创建类,定义属性,创建属性对应有参数构造方法
public class Orders {
//属性
private String oname;
private String address;
//有参数构造
public Orders(String oname,String address) {
this.oname = oname;
this.address = address;
} }
在 spring 配置文件中进行配置
<bean id="orders" class="spring5.Orders">
<constructor-arg name="oname" value="电脑"></constructor-arg>
<constructor-arg name="address" value="China"></constructor-arg>
</bean>
3.p 名称空间注入 添加 p 名称空间在配置文件中
xmlns:p="http://www.springframework.org/schema/p"
进行属性注入,在 bean 标签里面进行操作
<bean id="book" class="spring5.Book" p:bname="java" p:bauthor="无名氏"></bean>
7.如何注入集合属性
创建类,定义数组、list、map、set 类型属性,生成对应 set 方法
public class Orders {
//属性
private String oname;
private String address;
//有参构造
public Orders(String oname, String address) {
this.oname = oname;
this.address = address;
}
public void ordersTest(){
System.out.println(oname+"::"+address);
}
}
public class Stu {
//1 数组类型属性
private String[] courses;
//2 list 集合类型属性
private List<String> list;
//3 map 集合类型属性
private Map<String,String> maps;
//4 set 集合类型属性
private Set<String> sets;
public void setSets(Set<String> sets) {
this.sets = sets;
}
public void setCourses(String[] courses) {
this.courses = courses;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
} }
在 spring 配置文件进行配置
<bean id="stu" class="spring5.collectiontype.Stu">
<!--数组类型属性注入-->
<property name="courses">
<array>
<value>java 课程</value>
<value>数据库课程</value>
</array>
</property>
<!--list 类型属性注入-->
<property name="list">
<list>
<value>张三</value>
<value>小三</value>
</list>
</property>
<!--map 类型属性注入-->
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!--set 类型属性注入-->
<property name="sets">
<set>
<value>MySQL</value>
<value>Redis</value>
</set>
</property>
<!--注入 list 集合类型,值是对象-->
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
<!--创建多个 course 对象-->
<bean id="course1" class="spring5.collectiontype.Course">
<property name="cname" value="Spring5 框架"></property>
</bean>
<bean id="course2" class="spring5.collectiontype.Course">
<property name="cname" value="MyBatis 框架"></property>
</bean>
测试类
@Test
public void testCollection1(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Stu stu =context.getBean("stu",Stu.class);
stu.test();
}
9…spring管理bean的生命周期
(1)通过构造器创建 bean 实例(无参数构造) (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法) (3)调用 bean 的初始化的方法(需要进行配置初始化的方法) (4)bean 可以使用了(对象获取到了) (5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
public class Orders {
private String oname;
public Orders() {
System.out.println("第一步 执行无参数构造创建 bean 实例");
}
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步 调用 set 方法设置属性值");
}
//创建执行的初始化的方法
private void initMethod(){
System.out.println("第三步执行初始化方法");
}
//创建执行的销毁的方法
private void distoryMethod (){
System.out.println("第五步执行销毁方法");
}
}
<!--创建多个 course 对象 执行初始化方法 销毁方法-->
<bean id="orders" class="spring5.bean.Orders" init-method="initMethod" destroy-method="distoryMethod">
<property name="oname" value="手机"></property>
</bean>
@Test
public void testBean3(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
Orders orders =context.getBean("orders", Orders.class);
System.out.println("第四步 获取bean实例对象");
System.out.println(orders);
//手动让bean实例销毁
((ClassPathXmlApplicationContext) context).close();
}
结果
bean 的后置处理器,bean 生命周期有七步 (1)通过构造器创建 bean 实例(无参数构造) (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法) (3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization (4)调用 bean 的初始化的方法(需要进行配置初始化的方法) (5)把 bean 实例传递 bean 后置处理器的方法postProcessAfterInitialization (6)bean 可以使用了(对象获取到了) (7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
创建类,实现接口 BeanPostProcessor,创建后置处理器
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("在初始化之前执行的方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("在初始化之后执行的方法");
return bean;
} }
<!--配置后置处理器--> <bean id="myBeanPost" class="spring5.bean.MyBeanPost"></bean>
结果
10.bean的自动装配
public class Emp {
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp{" +
"dept=" + dept +
'}';
}
public void test(){
System.out.println(dept);
}
}
public class Dept {
@Override
public String toString() {
return "Dept{}";
}
}
xml文件 根据类型注入 此时id为dept或dept1都可以注入
<!--实现自动装配
bean 标签属性 autowire,配置自动装配
autowire 属性常用两个值:
byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
byType 根据属性类型注入
-->
<!-- <bean id="emp" class="spring5.autowire.Emp" autowire="byName">-->
<bean id="emp" class="spring5.autowire.Emp" autowire="byType">
<!-- <property name="dept" ref="dept" ></property>-->
</bean>
根据类型注入 此时id为dept
<bean id="dept1" class="spring5.autowire.Dept"></bean>
<!-- <bean id="dept" class="atguigu.spring5.autowire.Dept"></bean>-->
根据名称注入 此时id为dept1不可以可以注入
|