1、Spring5-第一天
- spring 是一个开源的免费框架
- spring是一个轻量级、非入侵式的框架
- 控制反转(IOC)、面向切面编程(AOP)
- 支持事务的处理,对框架的整合
spring是一个轻量级的控制反转和面向切面编程的框架
1.2、原来方式
- UserDao接口–UserDaoImpl实现类
- UserService业务接口-UserServicempl业务实现类
- 用户实际调用的是service层,service层调用dao层
如果在dao层增加了新的方法,又想在service调用该方法,则需在service层改变代码–新建实现类
因为你在代码里面写死了,新增加一个需求,就要改一个代码,牵一发动全身
private UserDao dao=new UserDaoImpl();
private UserDao dao1=new UserDaoMySqlImpl();
public void getUser() {
dao.getUser();
dao1.getUser();
}
1.3、spring方式
利用set进行动态的实现注入
private UserDao dao;
public void setDao(UserDao dao) {
this.dao = dao;
}
-
之前,所有的东西都是由程序去进行控制创建
-
使用set注入后,程序不在有主动性,而是被动的接收对象,把主动权交给了调用者
我们不需要再管理对象的创建,系统的耦合性降低,可以专注于在业务的实现上–这是IOC的原型
异常:class path resource [beans.xml] cannot be opened because it does not exist
路径错误 换相对路径即可 来自源根的路径
**我们不需要再在程序中更改,要实现不同的操作,只需要在xml配置文件修改 **
IOC:对象由Spring创建,管理,装配!
- 反转:程序本身不创建对象,而变成被动的接收对象
- 控制:之前是程序控制创建对象,现在用spring,由spring控制
- 依赖注入:利用set方法进行注入的(对象,成员变量)
<?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">
<bean id="daoImpl" class="IOC.com.xiaocong.dao.UserDaoImpl"></bean>
<bean id="mysqlImpl" class="IOC.com.xiaocong.dao.UserDaoMySqlImpl"></bean>
<bean id="UserServiceImpl" class="IOC.com.xiaocong.service.UserServiceImpl">
<property name="dao" ref="mysqlImpl"></property>
</bean>
</beans>
测试:
@Test
public void test1(){
ApplicationContext Context= new ClassPathXmlApplicationContext("IOC\\com\\beans.xml");
UserServiceImpl userServiceImpl = (UserServiceImpl) Context.getBean("UserServiceImpl");
userServiceImpl.getUser();
}
1.4、IOC创建对象方式
- 使用无参构造方法创建对象——默认
- 使用有参构造方法创建对象——注入属性
<bean id="user" class="xiaocong.User">
<!-- 通过有参构造方法-->
<constructor-arg name="name" value="李四"></constructor-arg>
<constructor-arg name="age" value="12"></constructor-arg>
</bean>
<bean id="userT" class="xiaocong.UserT"></bean>
在配置文件加载时候,spring容器管理的对象就已经初始化了
spring会创建所有的对象(默认调用无参构造方法)
1.5、依赖注入
-
构造器注入
1.4
-
set方式注入
-
set注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。
-
Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。
-
假设Bean显示定义了一个带参的构造函数,则需要同时提供一个默认无参的构造函数,否则使用属性注入时将抛出异常。
<bean id="student" class="xiaocong.Students">
<!-- 普通类型 普通注入-->
<property name="name" value="张三"></property>
<!-- 引用类型 bean注入-->
<property name="address" ref="address"></property>
<!-- 数组类型 数组注入-->
<property name="books">
<array>
<value>围城</value>
<value>白夜行</value>
</array>
</property>
<!-- List注入-->
<property name="hobbys">
<list>
<value>敲代码</value>
<value>睡觉</value>
</list>
</property>
<!-- Map注入-->
<property name="card">
<map>
<entry key="身份证" value="000011"></entry>
<entry key="手机号" value="1110"></entry>
</map>
</property>
<!-- Set注入-->
<property name="games">
<set>
<value>王者农药</value>
<value>英雄联盟</value>
</set>
</property>
<!-- null-->
<property name="wife" value=""></property>
<!-- properties注入-->
<property name="info">
<props>
<prop key="学号">0001</prop>
<prop key="pwd">0001</prop>
</props>
</property>
</bean>
<bean id="address" class="xiaocong.Address">
<property name="address" value="江西"></property>
</bean>
private String name;
private Address address;//引用类型
private String[] books;//数组
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private Properties info;
private String wife;
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
", address=" + address.toString() +
", books=" + Arrays.toString(books) +
", hobbys=" + hobbys +
", card=" + card +
", games=" + games +
", info=" + info +
", wife='" + wife + '\'' +
'}';
}
@Test
public void test2(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
Students student = (Students) context.getBean("student");
System.out.println(student.toString());
/**
* Students{name='张三',
* address=Address{address='江西'}, 对象
* books=[围城, 白夜行], 数组
* hobbys=[敲代码, 睡觉], list
* card={身份证=000011, 手机号=1110}, map
* games=[王者农药, 英雄联盟], set
* info={学号=0001, pwd=0001}, properties
* wife=''}
*/
}
2、Spring-第二天
2.1、Bean的自动装配–AutoWired
由spring帮你注入对象,不用自己手动注入(ref=id)
- byName:会自动在容器上下文查找,和自己对象set方法后面的值对应的 bean id唯一
- byType:会自动在容器上下文查找,和自己对象属性类型相同的 bean class,类型唯一
2.2、注解实现自动装配
-
环境搭建(xml配置):
- xmlns:context=“http://www.springframework.org/schema/context”
- “http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd”
- <context:annotation-config>:注解支持
- 报错可能是没有导入aop jar包
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 引入注解配置--> <context:annotation-config></context:annotation-config> <bean id="stu11" class="IOC.com.xiaocong.pojo.Student"></bean> <bean id="tec" class="IOC.com.xiaocong.pojo.Teacher"></bean> <bean id="person" class="IOC.com.xiaocong.pojo.Person"> <!-- 通过bean id--> <!-- <bean id="person" class="IOC.com.xiaocong.pojo.Person" autowire="byName">--> <!-- 通过bean class--> <!-- <bean id="person" class="IOC.com.xiaocong.pojo.Person" autowire="byType">--> <!-- set方法注入--> <!-- <property name="stu" ref="stu"></property>--> <!-- <property name="tec" ref="tec"></property>--> <!-- 构造器注入--> <!-- <constructor-arg name="stu" ref="stu"></constructor-arg>--> <!-- <constructor-arg name="tec" ref="tec"></constructor-arg>--> </bean> </beans>
-
直接加在属性的前面,可以不用set方法,前提是在spring容器中存在且符合id(set后面-属性)
@@Autowried
: 先根据类型(byType)注入,如果有满足的多个类型的对象,就会根据ID(byName)注入
@Autowried
private Dog dog;
@Autowried
private Cat cat;
@Nullable
:字段标记了这个注解,说明该字段可以为null
@Qualifier(value="bean id")
:和@AutowWried搭配使用(有多个bean id时使用),指定唯一的bean对象注入
@Resource
:类型唯一或名字唯一都可以(先通过bean id 再通过 bean class)
@Autowired
@Qualifier(value = "stu11")
private Student stu;
@Autowired
@Qualifier(value = "tec11")
private Teacher tec;
// @Resource
// private Student stu;
// @Resource
// private Teacher tec;
2.3、使用注解开发
<!-- 指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="IOC.com.xiaocong.dao"></context:component-scan>
//等价于:<bean id="userDaoImpl" class="IOC.com.xiaocong.dao.UserDaoImpl">
//相当于new 了一个对象
@Component
public class UserDaoImpl implements UserDao{
public void getUser() {
System.out.println("获取用户数据");
}
}
// 相当于<prpperty name="name" value="懒羊羊">
@Value("懒羊羊")
private String name;
public void show(){
System.out.println("学生学习");
}
2.4、AOP 在不影响业务的情况下,实现动态的增强
-
不通过修改源代码的方式,在主干功能中添加新的功能
-
底层使用动态代理
-
@Test public void test1(){ ApplicationContext con = new ClassPathXmlApplicationContext ("AOP\\com\\xiaocong\\applicationContext.xml"); //动态代理代理的是接口 UserService user = (UserService) con.getBean("userService"); user.select(); }
1、导包 aspectjweaver-1.9.6.jar
方法1:使用spring API接口
<!-- 注册bean-->
<bean id="userService" class="AOP.com.xiaocong.service.UserServiceImpl"></bean>
<bean id="log" class="AOP.com.xiaocong.log.Log"></bean>
<bean id="afterLog" class="AOP.com.xiaocong.log.AfterLog"></bean>
<!-- 配置AOP-->
<aop:config>
<!-- 切入点-->
<aop:pointcut id="pointcut" expression="execution(* AOP.com.xiaocong.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕增加-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"></aop:advisor>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
2、自定义类
<bean id="diy" class="AOP.com.xiaocong.diy.DiyPointcut"> </bean>
<aop:config>
<!-- 自定义切面,ref -要引用的类-->
<aop:aspect ref="diy">
<!-- 切入点-->
<aop:pointcut id="pointcut" expression="
execution(* AOP.com.xiaocong.service.UserServiceImpl.*(..))"/>
<!-- 通知-->
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<aop:after method="after" pointcut-ref="pointcut"></aop:after>
</aop:aspect>
</aop:config>
public class DiyPointcut {
public void before(){
System.out.println("++++方法执行前+++++");
}
public void after(){
System.out.println("++++方法执行后+++++");
}
}
3、注解实现
<!-- 方法3:注解实现-->
<bean id="annotationPointCut" class="AOP.com.xiaocong.diy.AnnotationPointCut"></bean>
<!-- 开启注解支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Aspect//标注该类是切面
public class AnnotationPointCut {
@Before("execution(* AOP.com.xiaocong.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("++++++方法执行前");
}
@After("execution(* AOP.com.xiaocong.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("+++++++++++方法执行后");
}
//在环绕增强中,可以给定一个参数,代表我们要获取处理切入的点
@Around("execution(* AOP.com.xiaocong.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前------------");
//执行方法
Object proceed = jp.proceed();
System.out.println("环绕后---------");
}
}