IOC

介绍:
在Spring的应用中,Spring IoC容器可以创建、装配和配置应用组件对象,这里的组件对象称为Bean。

Bean的实例化

在面向对象编程中,想使用某个对象时,需要事先实例化该对象。同样,在Spring框架中,想使用Spring容器中的Bean,也需要实例化Bean。Spring框架实例化Bean有3种方式:构造方法实例化、静态工厂实例化和实例工厂实例化,其中,最常用的实例方法是构造方法实例化。

创建配置类

在应用的src目录下,创建config包,并在该包中创建配置类JavaConfig。在该配置类中使用@Bean定义3个Bean,具体代码如下:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_spring

IOC操作bean管理(普通bean)

spring有两种类型bean,一种普通bean,另外一种工厂bean

普通bean:在配置文件中定义的什么类型就返回什么类型,工厂bean:返回的类型可以不是定义的类型

目前创建项目后文件目录:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_java_02


导入的jar包五个:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_spring_03


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

spring项目属性注入和bean管理xml 注入一般属性和集合属性_spring_04


spring项目属性注入和bean管理xml 注入一般属性和集合属性_xml_05

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>

结果:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_spring_06

级联赋值的第二种写法。直接在属性中注入:
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;
}

结果:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_spring_07

xml注入集合属性

1.注入数组类型

2.注入list集合类型

3.注入map类型属性

创建类,定义不同类型的属性

现在的目录:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_java_08


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>

结果:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_xml_09

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);
}

结果:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_java_10

工厂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();

}

运行后:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_xml_11


可以发现输出的内容是相同的,如果没有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包下创建类:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_java_12

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();
}

spring项目属性注入和bean管理xml 注入一般属性和集合属性_java_13

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配置文件实现和基于注解方式实现

引入外部属性文件:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_spring_14

spring项目属性注入和bean管理xml 注入一般属性和集合属性_java_15

基于注解的方式实现对象创建

第一步 引入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>

spring项目属性注入和bean管理xml 注入一般属性和集合属性_xml_16


四个注解:

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();
}

结果:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_java_17


value注入实例:

@Value(value="你好")
private String name;
public void add(){
System.out.println("service add"+name);
userdao.update();

再次运行测试类结果:

spring项目属性注入和bean管理xml 注入一般属性和集合属性_xml_18

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注解类型声明某类的实例是一个控制器

spring项目属性注入和bean管理xml 注入一般属性和集合属性_spring_19


AOP底层使用动态代理

第一种有接口,使用JDK动态代理

1.使用proxy类里面的方法创建代理对象

第二种没有接口,使用CGLIB动态代理