IOC
介绍:
在Spring的应用中,Spring IoC容器可以创建、装配和配置应用组件对象,这里的组件对象称为Bean。
Bean的实例化
在面向对象编程中,想使用某个对象时,需要事先实例化该对象。同样,在Spring框架中,想使用Spring容器中的Bean,也需要实例化Bean。Spring框架实例化Bean有3种方式:构造方法实例化、静态工厂实例化和实例工厂实例化,其中,最常用的实例方法是构造方法实例化。
创建配置类
在应用的src目录下,创建config包,并在该包中创建配置类JavaConfig。在该配置类中使用@Bean定义3个Bean,具体代码如下:

IOC操作bean管理(普通bean)
spring有两种类型bean,一种普通bean,另外一种工厂bean
普通bean:在配置文件中定义的什么类型就返回什么类型,工厂bean:返回的类型可以不是定义的类型
目前创建项目后文件目录:

导入的jar包五个:

这次下载的是5.2.6版本,用到了四个spring的jar包,是ioc需要的至少四个,直接jar包复制后新建lib文件夹,再粘贴到目录下,再手动添加jar包:


spring的官网地址:
https://repo.spring.io/release/org/springframework/spring/
common-logging-1.1.jar的下载地址:
https://mvnrepository.com/artifact/commons-logging/commons-logging/1.1
各个类中的代码:
Emp.java:
package com.company.bean;
public class Emp {
private String ename;
private String gender;
//员工属于某个部门
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public void setEname(String ename) {
this.ename = ename;
}
public void setGender(String gender) {
this.gender = gender;
}
//一个用于测试的方法
public void testt()
{
System.out.println(ename+" 性别"+gender+" "+dept);
}
public Dept getDept() {
return dept;
}
}
Dept.java:
package com.company.bean;
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
@Override
public String toString() {
return
"部门是:" + dname + '\'';
}
public String getDname()
{
return dname;
}
}
Userservice.java:
package com.company.service;
import com.company.dao.UserDao;
import com.company.dao.UserDaoimp;
public class Userservice {
//创建userdao类属性
private UserDao userdao;
public void setUserdao(UserDao userdao) {
this.userdao = userdao;
}
public void add()
{
System.out.println("servicee add..");
userdao.update();
}
public void setUserDao(UserDaoimp userDao) {
this.userdao=userDao;
}
}
Testdemo.java:
package com.company.spring5.testdemo;
import com.company.bean.Emp;
import com.company.service.Userservice;
import com.company.spring5.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Testdemo {
@Test
public void testAdd()
{
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Userservice userservice = context.getBean("userservice", Userservice.class);
userservice.add();
}
@Test
public void testbean2()
{
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
Emp emp=context.getBean("emp",Emp.class);
emp.testt();
}
@Test
public void testbean3()
{
ApplicationContext context=new ClassPathXmlApplicationContext("bean4.xml");
Emp emp=context.getBean("emp",Emp.class);
emp.testt();
}
}
bean2.xml:
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<bean id = "userservice" class="com.company.service.Userservice">
<!-- 注入userdao对象,name属性:类里面属性名称-->
<!-- ref属性:创建userdao对象bean标签的id值-->
<property name="UserDao" ref="userdaoimp"></property>
</bean>
<bean id = "userdaoimp" class="com.company.dao.UserDaoimp"></bean>
</beans>
UserDaoimp.java:
package com.company.dao;
public class UserDaoimp implements UserDao{
@Override
public void update() {
System.out.println("overider update");
}
}
内部bean(嵌套写法)和级联赋值
第一种写法。内部bean
bean3.xml:
<?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-->
<bean id="emp" class="com.company.bean.Emp">
<property name="ename" value="lucy"></property>
<property name="dept">
<bean id="dept" class="com.company.bean.Dept">
<property name="dname" value="财务部"></property>
<!-- 嵌套写法,在一个bean中嵌套另一个bean-->
</bean>
</property>
<property name="gender" value="女"></property>
</bean>
</beans>
注入属性–级联赋值
<bean id="emp" class="com.company.bean.Emp">
<property name="ename" value="lucy"></property>
<property name="dept" ref="dept"></property>
<property name="gender" value="女"></property>
<!-- 级联赋值:通过外部bean的方式引入,给属性赋值-->
</bean>
<bean id="dept" class="com.company.bean.Dept">
<property name="dname" value="人事部"></property>
</bean>
结果:

级联赋值的第二种写法。直接在属性中注入:
bean4.xml:
<bean id="emp" class="com.company.bean.Emp">
<property name="ename" value="lucy"></property>
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="人事部门之deptname"></property> <!--这种方法注入属性需要在Ept类中实现对Dept使用getter方法才可以使用-->
<property name="gender" value="女"></property>
</bean>
<bean id="dept" class="com.company.bean.Dept">
<property name="dname" value="Caiwu"></property>
</bean>
且在Emp中加上:
public Dept getDept() {
return dept;
}
结果:

xml注入集合属性
1.注入数组类型
2.注入list集合类型
3.注入map类型属性
创建类,定义不同类型的属性
现在的目录:

Testdemo1.Java
package testdemo;
import collection.Stu;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Testdemo1 {
@Test
public void testvalue()
{
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Stu stu= context.getBean("stu", Stu.class);
stu.ontest();
}
}
Stu.java:
package collection;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Stu {
private String[] lesson;//属性 课程(有多门课程)
public void setLesson(String[] lesson)
{
this.lesson=lesson;
}
private List<String> newlist;//list类型的属性
private Map<String,String> newmap;//Map类型的属性
private Set<String>newset;
public void setNewlist(List<String> newlist) {
this.newlist = newlist;//setter方法
}
public void setNewset(Set<String> newset) {
this.newset = newset;
}
public void setNewmap(Map<String, String> newmap) {
this.newmap = newmap;
}
public void ontest()
{
System.out.println(Arrays.toString(lesson));
System.out.println(newlist);
System.out.println(newmap);
System.out.println(newset);
}
}
bean1.xml:
<?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="stu" class="collection.Stu">
<property name="lesson" >
<array>
<value>语文</value>
<value>数学</value>
<value>english</value>
</array>
</property>
<property name="newlist">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="newmap">
<map>
<entry key="张三" value="第一名"></entry>
<entry key="李四" value="第二名"></entry>
<entry key="王五" value="第三名"></entry>
</map>
</property>
<property name="newset">
<set>
<value>c语言</value>
<value>Java</value>
<value>html</value>
<value>css</value>
</set>
</property>
</bean>
</beans>
结果:

IOC操作工厂bean
第一步:创建类,让这个类作为工厂bean,实现接口factorybean
第二步:实现接口里面的方法,在实现的方法中定义返回的bean类型
先创建一个类:
package factorybean;
public class Mybean {
@Override
public String toString() {
return "Mybean{}";
}
}
bean2.xml进行配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
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="mybook" class="factorybean.Mybean">
</bean>
</beans>
测试类:
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Mybean mybook = context.getBean("mybook", Mybean.class);
System.out.println(mybook);
}
结果:

工厂bean设置返回的bean:
public class Mybean implements FactoryBean<Dept> {
@Override//定义返回的bean
public Dept getObject() throws Exception {
Dept dept = new Dept();
dept.setDname("财务");
return dept;
}
测试类:
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Dept dept = context.getBean("mybook", Dept.class);
System.out.println(dept);
}
注意这句话 Dept dept = context.getBean(“mybook”, Dept.class);中的"mybook"跟
<bean id="mybook" class="factorybean.Mybean">
</bean>
中的id是对应的关系,否则会报错。
Dept类:
package com.company.bean;
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
@Override
public String toString() {
return
"部门是:" + dname + '\'';
}
public String getDname()
{
return dname;
}
}
bean作用域
在spring里面,默认情况下是单实例对象
可以测试:
@Test
public void testvalue()
{
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Stu stu= context.getBean("stu", Stu.class);
Stu stu2 = context.getBean("stu",Stu.class);
stu.ontest();
stu2.ontest();
}
运行后:

可以发现输出的内容是相同的,如果没有tostring方法,输出的地址是相同的,也可以证明是单实例
singleton单实例 prototype多实例
<bean id="stu" class="collection.Stu" scope="prototype">
设置为多实例对象
bean生命周期
(1)通过构造器创建bean实例(无参数构造),
(2)为bean的属性设置值和对其他bean的引用(调用set方法)
(3)调用bean的初始化方法(需要进行配置)
(4)bean可以使用了(对象获取到了0
(5)当容器关闭的时候,调用bean的销毁方法
代码: 在bean包下创建类:

package com.company.bean;
import org.w3c.dom.ls.LSOutput;
public class Orders {
public Orders() {
System.out.println("第一步创建对象");
}
private String oname;
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步调用set方法设置属性值");
;
}
public void initmethod(){
System.out.println("执行初始化");
}
public void destroymethod(){
System.out.println("执行销毁");
}
}
bean3.xml:
<?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="orders" class="com.company.bean.Orders" init-method="initmethod" destroy-method="destroymethod">
<property name="oname" value="手机" />
</bean>
</beans>
测试类:
@Test
public void test3(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
Orders orders = context.getBean("orders", Orders.class);
System.out.println("第四步 获取创建bean实例对象");
System.out.println(orders);
((ClassPathXmlApplicationContext)context).close();
}

xml自动装配
什么是自动装配:根据指定装配规则(属性名称或者属性类型),spring自动将匹配的属性值进行注入
<!--实现自动装配
bean标签 autowire属性
配置自动装配
autorire属性常用两个值:
byNane根据属性名称注入,注入值bean的id值和类属性名称一样
bype根据属性类型注入-->
<bean id= “emp" class= "com.company.bean. Emp" autowired="byType">.
<!--property name=" dept" ref ="dept"></property>-->
</bean>
<bean id ="dept"class="com.company.bean.Dept"</bean>
bean管理操作有两种方式:基于xml配置文件实现和基于注解方式实现
引入外部属性文件:


基于注解的方式实现对象创建
第一步 引入aop依赖
第二步 开启组件扫描
如果扫描多个包,可以多个包用逗号隔开,也可以扫描上层目录
<?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">
<context:component-scan base-package="com"></context:component-scan>
</beans>

四个注解:
1.@Component @Component 是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上,@Component不推荐使用。
2.@Controller @Controller对应表现层的Bean,.
3.@ Service @Service对应的是业务层Bean
4.@ Repository @Repository对应数据访问层Bean ,
这四个注解功能是一样的都能实现创建bean实例,只是在写代码时为了方便项目管理出于开发习惯才这样区分
基于注解方式实现属性注入
@Autowired:根据属性类型进行自动装配
@Qualifier:根据属性名称进行注入
@Resource: 可以根据类型注入也可以根据名称注入
@Value: 注入普通类型属性
@service
public class UserService{
//定义dao类型属性
//不需要添加set方法
//添加注入属性注解
@Autowired
private UserDao userDao;
publie void add(){
System.out.printIn("service add.."
);
userDao. add();
}
用Autowierd注入属性实例:
先导入aop的jar包
xml文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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:component-scan base-package="com.company"></context:component-scan>
</beans>
dao层:
package com.company.dao;
public interface UserDao {
//public void add;
public void update();
}
package com.company.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoimp implements UserDao{
@Override
public void update() {
System.out.println("overider update");
}
}
service层:
package com.company.service;
import com.company.dao.UserDao;
import com.company.dao.UserDaoimp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@Repository
public class Userservice {
//创建userdao类属性
@Autowired
private UserDao userdao;
public void add(){
System.out.println("service add");
userdao.update();
}
测试:
@Test
public void Testservice(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
Userservice userservice = context.getBean("userservice",Userservice.class);
System.out.println(userservice);
userservice.add();
}
结果:

value注入实例:
@Value(value="你好")
private String name;
public void add(){
System.out.println("service add"+name);
userdao.update();
再次运行测试类结果:

AOP
Spring MVC是一款优秀的基于MVC思想的应用框架,它是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架。Spring MVC框架主要由DispatcherServlet、处理器映射、控制器、视图解析器、视图组成,总结出Spring MVC的工作流程如下:
(1)客户端请求提交到DispatcherServlet。
(2)由DispatcherServlet控制器寻找一个或多个HandlerMapping,找到处理请求的Controller。
(3)DispatcherServlet将请求提交到Controller。
(4)Controller调用业务逻辑处理后,返回ModelAndView。 (5)DispatcherServlet寻找一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
(6)视图负责将结果显示到客户端。
patcherServlet将请求分发给Controller之前,需要借助于Spring MVC提供的HandlerMapping定位到具体的Controller。 HandlerMapping接口负责完成客户请求到Controller映射。 Controller接口将处理用户请求,这和Java Servlet扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。从宏观角度考虑,DispatcherServlet是整个Web应用的控制器;从微观角度考虑,Controller是单个Http请求处理过程中的控制器,而ModelAndView是Http请求过程中返回的模型(Model)和视图(View)。 ViewResolver接口(视图解析器)在Web应用中负责查找View对象,从而将相应结果渲染给客户。
基于注解的控制器
在使用Spring MVC进行Web应用开发时,**Controller是Web应用的核心。Controller实现类包含了对用户请求的处理逻辑,是用户请求和业务逻辑之间的“桥梁”,**是Spring MVC框架的核心部分,负责具体的业务逻辑处理。
AOP(概念)
1、什么是AOP
(1)面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得
业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
(2)通俗描述:不通过修改源代码方式,在主千功能里面添加新功能
(3)使用登录例子说明AOP
Controller注解类型
在Spring MVC中,使用org.springframework.stereotype.Controller注解类型声明某类的实例是一个控制器

AOP底层使用动态代理
第一种有接口,使用JDK动态代理
1.使用proxy类里面的方法创建代理对象
第二种没有接口,使用CGLIB动态代理