Spring负责管理项目中的所有对象,Spring看作是项目中对象的管家
Spring框架的功能:aop支持、ioc思想、spring jdbc、aop事务、junit测试支持
Spring搭建:
导包:beans、context、core、exception四个基础包
日志包
创建实体类对象
书写配置文件:建议文件名为applicationContext.xml
导入约束文件Schema约束
代码测试:1、创建容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext(“applicationContext.xml”);
2、从容器中获得实体对象
User user=(User)ac.getBean(“User”);
3、打印该对象
System.out.println(user);
Spring思想:
ioc:反转控制
反转控制就是创建对象的方式反转了。以前对象的创建由开发人员自己维护,包括依赖关系也是自己注入;使用spring之后,对象的创建以及以来关系可以由spring完成创建以及注入。
反转控制就是反转了对象的创建方式。从我们自己创建反转给了程序
di:依赖注入(注入就是赋值)
实现ioc思想需要di做支持
注入的方式:set方法注入、构造方法注入、字段注入
注入的类型:值类型注入---8大基本数据类型
引用类型注入---将依赖对象注入
ApplicationContext&BeanFactory
接口:spring原始接口,针对原始接口的实现类功能较为单一
接口实现类的容器,特点是每次在获得对象时才会创建对象
每次容器启动时就创建容器中配置的所有对象,并提供更多的功能
从类路径下加载配置文件:ClassPathXmlApplicatiionContext
从硬盘绝对路径下加载配置文件:FileSystemXmlApplicationContext(d:/aaa/ddd/fff)
总结:在web开发中,使用applicationContext,在资源匮乏时使用BeanFactory。
Spring配置文件详解:
元素:
将User对象交给spring容器管理
元素:使用该元素描述需要spring容器管理的对象
属性:被管理对象的完整类名
属性:给被管理的对象起个名字。获得对象时根据该名称获得对象,可以重复,可以使用特殊字符(尽量使用name属性)
属性:与name属性一模一样,但是名称不可重复,不能使用特殊字符
创建对象的方式:
空参构造方式:<bean name=”user” class=”com.domain.User”></bean>
元素进阶:
属性
(默认值):单例对象,被标识为单例的对象在spring容器中只会存在一个实例
:多例原型,被标识为多例的对象,每次再获得再会创建,每次创建都是新的对象。
的分模块配置
导入其他spring配置文件-->
<import resource=”com.domain/applicationContext.xml”/>
Spring属性注入:
方法注入
构造函数注入
复杂类型注入(数组、list、map、properties)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">
<!-- 将User对象交给Spring容器来管理 -->
<!-- 通过set方法进行注入 -->
<bean name="user" class="com.domain.User">
<!-- 值注入,也就是变量赋值 -->
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
<!-- 引用类型注入 -->
<property name="car" ref="car"></property>
</bean>
<bean name="car" class="com.domain.Car">
<!-- 值注入 -->
<property name="cname" value="兰博基尼"></property>
<property name="color" value="黄色"></property>
</bean>
<!-- 通过构造方法进行注入 -->
<bean name="user1" class="com.domain.User">
<constructor-arg name="name" value="8" index="0" type="java.lang.Integer"></constructor-arg>
<constructor-arg name="car" ref="car" index="1"></constructor-arg>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">
<!-- 通过set方法进行注入 -->
<bean name="user" class="com.domain.User">
<!-- 值注入,也就是变量赋值 -->
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
<!-- 引用类型注入 -->
<property name="car" ref="car"></property>
</bean>
<bean name="car" class="com.domain.Car">
<!-- 值注入 -->
<property name="cname" value="兰博基尼"></property>
<property name="color" value="黄色"></property>
</bean>
<bean name="cd" class="com.collection.CollectionDemo">
<!-- 数组 -->
<property name="arr">
<array>
<!-- 值注入 -->
<value>张三</value>
<value>李四</value>
<!-- 引用注入 -->
<ref bean="user" />
</array>
</property>
<!-- List集合 -->
<property name="list">
<list>
<value>孙悟空</value>
<value>猪八戒</value>
<ref bean="car" />
</list>
</property>
<!-- Map类型注入 -->
<property name="map">
<map>
<entry key="123" value="asd"></entry>
<entry key="user" value-ref="car"></entry>
<entry key-ref="user" value-ref="car"></entry>
</map>
</property>
<!-- properties类型注入 -->
<property name="prop">
<props>
<prop key="driver">123</prop>
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
</beans>
package com.collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.domain.User;
public class Demo {
@Test
public void method1() {
// 1.得到容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml");
// 2.管容器要一个对象
CollectionDemo cd = (CollectionDemo) ac.getBean("cd");
Object[] obj = cd.getArr();
for (Object o : obj) {
System.out.println(o);
}
}
@Test
public void method2() {
// 1.得到容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml");
// 2.管容器要一个对象
CollectionDemo cd = (CollectionDemo) ac.getBean("cd");
// 管对象要一个list
List list = cd.getList();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
@Test
public void method3() {
// 1.得到容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml");
// 2.管容器要一个对象
CollectionDemo cd = (CollectionDemo) ac.getBean("cd");
// 管对象要一个map
Map map = cd.getMap();
Set set = map.entrySet();
Iterator<Map.Entry> it = set.iterator();
while (it.hasNext()) {
Map.Entry m = it.next();
System.out.println(m.getKey() + "---" + m.getValue());
}
}
@Test
public void method4() {
// 1.得到容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml");
// 2.管容器要一个对象
CollectionDemo cd = (CollectionDemo) ac.getBean("cd");
// 管对象要一个properties
Properties prop = cd.getProp();
Set<String> set = prop.stringPropertyNames();
for (String str : set) {
System.out.println(str + "--" + prop.getProperty(str));
}
}
}
使用注解配置spring
1、为主配置文件引入新的命名空间(约束)
2、开启使用注解代理配置文件
3、在类中使用注解完成配置
将对象注入到容器
@Component(“user”)
层
层
层
修改对象的作用范围
@Scope(scopeName=”prototype”)
值类型注入:@Value(“tom”)
通过反射的Field赋值,破坏了封装性
@Value(“tom”)
Public void setName(String name){
This.name=name;
}//通过set方法赋值,推荐使用
引用类型注入:@Autowired//自动装配
使用@Qualifier注解告诉spring容器自动装配哪个名称的对象
两个配置使用
初始化|销毁方法
@PostConstruct //在对象被创建后调用,init-method
@PreDestory //在销毁之前调用,destory-method
Spring与Junit整合测试:
导包:基础包4个和日志包两个+aop+test
配置注解:@RunWith(SpringJunit4ClassRunner.class)//帮我们创建容器
指定创建容器时使用哪个配置文件
测试
package com.service;
//目标对象(UserService被代理的对象)
public class UserService {
public void add() {
System.out.println("这是新增的方法");
}
public void delete() {
System.out.println("这是删除的方法");
}
public void update() {
System.out.println("这是更新的方法");
}
public void find() {
System.out.println("这是查找的方法");
}
}
package com.service;
//spring与Junit的整合,适用于测试
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.domain.User;
//创建容器
@RunWith(SpringJUnit4ClassRunner.class)
// 指定创建容器时使用哪个配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo01 {
@Autowired
@Qualifier("userService")
private UserService userService;
@Test
public void method() {
userService.add();
}
}
aop思想
能够为容器中管理的对象生成动态代理对象
动态代理(优先):被代理的对象必须实现接口,才能产生代理对象,如果没有,将不能产生动态代理技术
代理(没有接口):第三方代理技术,cglib代理。可以对任何类生成代理。代理的原理是对目标对象进行继承代理。如果目标对象被final修饰,那么该类无法被cglib代理。
名词学习:
连接点):目标对象中,所有可以增强的方法
(切入点):目标对象,已经增强的方法
(通知/增强):增强的代码
(目标对象):被代理对象
(织入):将通知应用到切入点的过程
(代理):将通知织入到目标对象之后,形成代理对象
(切面):切入点+通知
package com.service;
import org.aspectj.lang.ProceedingJoinPoint;
//通知
public class MyAdvice {
// 前置通知
public void before() {
System.out.println("这是前置通知");
}
// 后置通知
public void afterReturning() {
System.out.println("这是后置通知,在异常的时候不调用");
}
// 环绕通知
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("这是环绕通知之前的部分");
Object proceed = pjp.proceed();
System.out.println("这是环绕通知之后的部分");
return proceed;
}
// 异常通知
public void afterException() {
System.out.println("这是异常通知,在出现异常的时候调用");
}
// 后置通知
public void after() {
System.out.println("后置通知,在出现异常的时候调用");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd ">
<!-- 配置目标对象 -->
<bean name="userService" class="com.service.UserService"></bean>
<!-- 配置通知 -->
<bean name="myAdvice" class="com.service.MyAdvice"></bean>
<!-- 配置切入点 -->
<aop:config>
<aop:pointcut expression="execution(* com.service.*Service.*(..))" id="pc"/>
<aop:aspect ref="myAdvice">
<aop:before method="before" pointcut-ref="pc"/>
<aop:after-returning method="afterReturning" pointcut-ref="pc"/>
<aop:around method="around" pointcut-ref="pc"/>
<aop:after-throwing method="afterException" pointcut-ref="pc"/>
<aop:after method="after" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
</beans>