Spring学习笔记
spring
1.1 简介
- spring : 春天 给程序员带来了春天
- 2002 ,首次推出了spring雏形。
- spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日发布1.0正式版
- Spring Framework创始人,著名作者。 Rod在悉尼大学不仅获得了计算机学位,同时还获得了音乐学位。更令人吃惊的是在回到软件开发领域之前,他还获得了音乐学的博士学位。 有着相当丰富的C/C++技术背景的Rod早在1996年就开始了对Java服务器端技术的研究。
- spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架
- SSH:struct2 + Spring + Hibernate
- SSM:SpringMVC + spring + MyBatis
- 学习官方文档:https://docs.spring.io/spring-framework/docs/5.2.11.RELEASE/spring-framework-reference/core.html#spring-core
- 官网:https://spring.io/projects/spring-framework#overview
- 官方下载地址:https://repo.spring.io/release/org/springframework/spring/
- GitHub:https://github.com/spring-projects/spring-framework
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
-
beans.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 https://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
1.2,优点
- spring 是一个开源的免费的框架(容器)
- spring是一个轻量级的,非侵入式的框架
- 控制反转(IOC),面向切面编程(AOP)
- 支持十五处理,对框架整合支持
1.3,spring的组成
The following diagram shows a high-level view of how Spring works. Your application classes are combined with configuration metadata so that, after the ApplicationContext
is created and initialized, you have a fully configured and executable system or application.
1.4,扩展
- spring boot
- 一个快速的开发脚手架
- 基于Springboot可以快速的开发单个微服务
- 约定大量配置
- spring cloud
- springcloud是基于Springboot实现的
因为现在大多数的公司都在使用Spring Boot进行快速的开发,学习springboot的前提需要掌握spring,springmvc。承上启下。
弊端:发展太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱
1.5 IOC理论(控制反转)
在面向对象的传统方式中,获取对象的方式通常是用new关键字主动创建一个对象。spring中的Ioc方式对象的生命周期有spring框架提供的ioc容器来管理,直接从IoC容器中获取一个对象,控制权从应用程序交给了IoC容器。理论上是借助于“第三方”实现具有依赖关系对象之间的解耦,如下图,即把各个对象类封装之后,通过IoC容器来关联这些对象类。这样对象于对象之间就通过IoC容器进行联系,而对象与对象之间就没有什么联系。
应用程序没有引入IoC容器之前,对象A依赖对象B,那么A对象在实例化或者运行到某一点的时候,自己必须主动创建对象B或者使用已经创建好的对象B,其中无论是创建还是使用自己创建的对象B控制权都在应用程序自身。如果应用程序引入IoC容器之后,对象A和对象B之间失去了直接联系,那么当对象A实例化和运行时,如果需要对象B,IoC容器就会主动创建一个对象B注入(依赖注入)到对象A所需要的地方。由此,对象A获得依赖对象B的过程,由主动行为变成被动行为,即把创建对象交给了IoC容器处理,控制权颠倒了过来,这就是所谓的控制反转。
在之前的业务中,用户的需求可能会影响我们原来的代码,我们需要更具用户的需求区修改原来的代码!如果程序代码量十分巨大,修改一次的成本代价回十分昂贵!
我们可以使用一个set接口实现,已经发生了革命性的变化
private UserDao userDao;
//利用set进行动态实现值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
之前,程序是主动创建对象!控制权在程序员手中
使用set注入,程序不在具有主动性,而是变成了被动的接受对象!
这种思想从本质上解决了问题,我们程序员不用再去管理对象的创建,系统的耦合性大大降低,可以更加专注在业务逻辑上
注意:事实上依赖注入和控制反转是对同一件事情的不同描述,从某个方面说,就是他们描述的角度不同。依赖注入是从应用程序的角度描述,即应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度描述,即容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。外部资源可以是外部文件或对象。
1.6 IoC创建对象的方式
-
使用无参构造函数创建对象,默认
-
使用有参构造函数创建对象。
-
下标赋值
<!-- 第一种赋值,下标赋值 --> <bean id="user" class="com.qijian.pojo.User"> <constructor-arg index="0" value="mahuahong"/> </bean>
-
类型赋值
<bean id="user" class="com.qijian.pojo.User"> <!-- 类型赋值--> <!-- 通过类型创建对象--> <constructor-arg type="java.lang.String" value="qijian"/> </bean>
-
通过参数名赋值
<bean id="user" class="com.qijian.pojo.User"> <!-- 通过参数名创建对象--> <constructor-arg name="name" value="柒间"/>
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了。
-
2.1spring配置
-
别名,如果添加了别名也可以通过别名获取对象
<alias name="user" alias="newname"/>
-
Bean的配置
<!-- id : bean 的唯一标识,也就是相当于对象名 class : bean 对象所对应的全限定名 : 包+类 name : 也就是别名 可以同时取多个别名 --> <bean id="us" class="com.qijian.pojo.User" name="user,us1"/>
-
import 一般用于团队开发使用,它可以配置对各配置文件,导入合并为一个
假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册不同的Bean中,我们可以用import将所有的bean.xml合并为一个。只用的时候直接使用总的(applicationContex.xml)即可。
<import resource="beans.xml"/> <import resource="beans1.xml"/>
3 依赖注入
3.1 构造器注入
3.2 Set方式注入【重点】
-
依赖注入:Set注入!
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
-
【环境的搭建】
-
Address类
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "address='" + address + '\'' + '}'; } }
-
Students类
public class Student { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> game; private String wife; private Properties info; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public List<String> getHobbys() { return hobbys; } public void setHobbys(List<String> hobbys) { this.hobbys = hobbys; } public Map<String, String> getCard() { return card; } public void setCard(Map<String, String> card) { this.card = card; } public Set<String> getGame() { return game; } public void setGame(Set<String> game) { this.game = game; } public String getWife() { return wife; } public void setWife(String wife) { this.wife = wife; } public Properties getInfo() { return info; } public void setInfo(Properties info) { this.info = info; } public Student(){} @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", address=" + address.toString() + ", books=" + Arrays.toString(books) + ", hobbys=" + hobbys + ", card=" + card + ", game=" + game + ", wife='" + wife + '\'' + ", info=" + info + '}'; } }
-
bean.xml配置
<bean id="address" class="com.qijian.pojo.Address"/> <bean id="student" class="com.qijian.pojo.Student"> <!-- 普通注入 value--> <property name="name" value="qijan"/> <!-- Beans注入 ref--> <property name="address" ref="address"/> <!-- 数组注入 --> <property name="books"> <array> <value>think in java</value> <value>计算机原理</value> <value>SSM从入门到精通</value> </array> </property> <!-- list--> <property name="hobbys"> <list> <value>写代码</value> <value>听歌</value> </list> </property> <!-- Map--> <property name="card"> <map> <entry key="身份证" value="000000000000"/> <entry key="银行卡" value="1111111111"/> </map> </property> <!-- Set--> <property name="game"> <set> <value>王者荣耀</value> <value>刺激战场</value> </set> </property> <!-- null--> <property name="wife"> <null/> </property> <!-- properties--> <property name="info"> <props> <prop key="Driver">222222</prop> <prop key="sex">男</prop> <prop key="name">qijian</prop> <prop key="pwd">root</prop> </props> </property> </bean>
-
测试类
import com.qijian.pojo.Student; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class mytest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.toString()); /*输出 Student{ name='qijan', address=Address{a ddress='null' }, books=[ think in java, 计算机原理, SSM从入门到精通 ], hobbys=[ 写代码, 听歌 ], card={ 身份证=000000000000, 银行卡=1111111111 }, game=[ 王者荣耀, 刺激战场 ], wife='null', info={ name=qijian, Driver=222222, sex=男, pwd=root } } */ } }
3.3,其他方式注入
需要注意的是c名命空间和p名命空间不能直接使用需要导入xml约束
c:
xmlns:c="http://www.springframework.org/schema/c"
p:
xmlns:p="http://www.springframework.org/schema/p"
User类
package com.qijian.pojo;
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
-
p名命空间注入
** The p-namespace lets you use the
bean
element’s attributes (instead of nested<property/>
elements) to describe your property values collaborating beans, or both.P-namespace **
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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="com.qijian.pojo.User" p:name="qijian" p:age="18" /> </beans>
-
c名命空间注入(通过构造器注入)
Similar to the XML Shortcut with the p-namespace, the c-namespace, introduced in Spring 3.1, allows inlined attributes for configuring the constructor arguments rather then nested
constructor-arg
elements. **与 p 名称空间的 XML Shortcut 类似,Spring 3.1中引入的 c 名称空间允许内联属性配置构造函数参数,而不是嵌套的构造函数-arg 元素。 **
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="com.qijian.pojo.User"> <constructor-arg name="name" value="柒间"/> <constructor-arg name="age" value="19"/> </bean> //c名命空间注入 <bean id="user1" class="com.qijian.pojo.User" c:name="qijianc" c:age="18"/> </beans>
c名命空间注入需要由有参构造函数
*** 注意 ***
Null and Empty String Values
//Spring 将属性和类似属性的空参数视为空字符串。下面的基于 xml 的配置元数据片段将 email 属性设置为空 String 值(“”)。
<bean class="ExampleBean">
<property name="email" value=""/>
</bean>
上面相当于String email=“”;
//The <null/> element handles null values
<bean class="ExampleBean">
<property name="email">
<null/>
</property>
</bean>
上面的注入等价于String email = null;
3.4 ,bean的作用域
1,单例模式(spring默认机制)
只管理单一 bean 的一个共享实例,对 ID 或 ID 与 bean 定义相匹配的 bean 的所有请求都将导致 Spring 容器返回一个特定 bean 实例。
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>
下面的图片展示了单例模式的工作原理:
2,原型模式
The non-singleton prototype scope of bean deployment results in the creation of a new bean instance every time a request for that specific bean is made. That is, the bean is injected into another bean or you request it through a getBean()
method call on the container. As a rule, you should use the prototype scope for all stateful beans and the singleton scope for stateless beans.
Bean 部署的非单例原型范围导致每次对特定 bean 发出请求时都会创建一个新的 bean 实例。也就是说,bean 被注入到另一个 bean 中,或者您通过容器上的 getBean ()方法调用请求它。通常,您应该为所有有状态 bean 使用原型范围,为无状态 bean 使用单例范围。
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
下图说明了 Spring 的原型范围:
注意:每次从容器中get的时候,都会产生一个新的对象!
3,其余的request,session,application,这些只能在web开发中使用到!
4,bean的自动装配
环境:
Cat.class
package com.qijan.pojo;
public class Cat {
public void shout(){
System.out.println("miao~~~");
}
}
Dog.class
package com.qijan.pojo;
public class Dog {
public void shout(){
System.out.println("wang~~");
}
}
People.class
package com.qijan.pojo;
import com.qijan.pojo.Cat;
import com.qijan.pojo.Dog;
public class People {
private String name;
private Cat cat;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
"\n, cat=" + cat +
"\n, dog=" + dog +
'}';
}
}
bean.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.qijan.pojo.Cat"/>
<bean id="dog" class="com.qijan.pojo.Dog"/>
<!-- <bean id="people" class="com.qijan.pojo.People">-->
<!-- <property name="name" value="qijian"/>-->
<!-- <property name="dog" ref="dog"/>-->
<!-- <property name="cat" ref="cat"/>-->
<!-- </bean>-->
<!-- 自动装配 byName:会自动在容器上下文查找,和自己对象set方法后面的值对应的bean id-->
<bean id="people" class="com.qijan.pojo.People" autowire="byName">
<property name="name" value="qijian"/>
</bean>
</beans>
测试类
import com.qijan.pojo.People;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
People people = context.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
System.out.println(people.toString());
}
}
- 自动装配是Spring满足bean依赖的一种方式
- Spring会在上下文寻找,并自动给bean装配属性!;
在spring中有三种装配方式
- 在xml中显示的配置
- 在Java中显示的配置
- 隐式的自动装配bean【重要】
4.1,ByName自动装配
<bean id="cat" class="com.qijan.pojo.Cat"/>
<bean id="dog" class="com.qijan.pojo.Dog"/>
<!-- <bean id="people" class="com.qijan.pojo.People">-->
<!-- <property name="name" value="qijian"/>-->
<!-- <property name="dog" ref="dog"/>-->
<!-- <property name="cat" ref="cat"/>-->
<!-- </bean>-->
<!-- 自动装配 byName:会自动在容器上下文查找,和自己对象set方法后面的值对应的bean id-->
<bean id="people" class="com.qijan.pojo.People" autowire="byName">
<property name="name" value="qijian"/>
</bean>
4.2 byType自动装配
<bean class="com.qijan.pojo.Dog"/>
<bean class="com.qijan.pojo.Cat"/>
<!-- 自动装配 byType: 会自动在容器上下文查找,和自己对象属性类型相同的bean
可以不用设置bean id
-->
<bean id="people" class="com.qijan.pojo.People" autowire="byType">
<property name="name" value="qijian"/>
</bean>
小结:
- byName:需要保证bean的id的唯一,并且这个bean需要和自动注入的属性的set方法的值一致
- byType:需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
4.4,使用注解实现自动装配
jdk1.5 开始支持注解,spring2.5开始支持注解
要使用注解须知:
-
导入约束
-
配置注解支持
您可以将它们注册为单独的 bean 定义,但也可以通过在基于 xml 的 Spring 配置中包含以下标记来隐式注册它们(注意包含上下文名称空间) :
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/>//注解的支持,需要添加进去。 </beans>
@Autowired
直接在属性上使用即可!也可以在set方法使用!
使用Autowired我们可以不用编写Set方法,前提是你的这个自动装配的属性在(spring)容器中存在,且符合名字byname!
@Nullable 字段标记了这个注解,说明这个字段可以为null
public @interface Autowired{ boolean required() default true; }
代码测试:
//使用在属性上
// 如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空 // @Autowired(required = false) @Autowired private Cat cat; public People(@Nullable Cat cat) { this.cat = cat; }
//对构造函数应用@autowired 注释,如下面的例子所示:
public class People{ private String name; ... @Autowired public void People(String name){} ... }
//可以将@autowired 注释应用于传统的 setter 方法,如下面的示例所示:
public class People{ private String name; ... @Autowired public void setName(String name){ this.name = name; } }
//还可以将注释应用于具有任意名称和多个参数的方法等。
如果@Autowired自动装配的环境比较复杂,自动装配无法通过注解【@AutoWired】完成的时候,我们可以使用@Qualifier(value=”newcatName”)去配合@Autowired的使用,指定一个唯一的bean对象注入
public class People{ @Autowired @Qualifier(value="newcatname") private Cat cat; @Autowired @Qualifier(value="nawdogname") private Dog dog; ... }
注意:@Qualifier于@Autowired注解配合使用,会将默认的按bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的指定。
从 Spring Framework 4.3开始,如果目标 bean 从一开始就只定义一个构造函数,那么在这样的构造函数上就不再需要@autowired 注释了。但是,如果有多个构造函数可用,并且没有主/默认构造函数,那么至少有一个构造函数必须用@autowired 注释,以便指示容器使用哪个构造函数。有关详细信息,请参阅关于构造函数解析的讨论。
-
@resource功能比较强大,但是使用的较少
public class People{ @Resource(name="cat2") private Cat cat; @Resource private Dog dog; ... }
注意:
@Resource和@Autowired的区别
- 都是用来自动装配的,都可以放在属性字段上
- @Autowired通过byName的方式实现
- @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就会报错!
- 执行的顺序不同:@Autowired
5,使用注解开发
在Spring4之后,要使用注解开发,必须要保证aop的包导入,使用注解需要导入context约束,增加注解的支持!
-
bean
-
属性如何注入
//java文件
package com.qijian.pojo; import org.springframework.stereotype.Component; @Component public class User { private String name = "qijian"; @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } }
//配置文件
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 指定扫描的包,这个包下的注解会生效--> <context:component-scan base-package="com.qijian.pojo"/> <!-- 注解--> <context:annotation-config/> </beans>
-
衍生注解
@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!
-
dao【@Repository】
-
service【@Service】
-
controller【@Controller】
这四个注解功能时一样的,都是代表将莫格1类注册到Spring中
-
-
自动装配
@Autowired,@Qualifier(value =”XXX”),@Resource
-
作用域
@Scope 例如:@Scope(“prototype”) 写在类的上面
@Component @Scope("prototype") public class People{ // @Value("qijian") private String name; //相当于<property name="name" value="qijian"> @Value("qijian")//写在此处与写在属性上面时一样的,但是如果复杂的注入时不建议使用 public void setName(String name){ this.name=name; } }
-
小结:
xml与注解
-
xml更加万能,适用于任何场合!维护简单方便
-
注解不是自己类使用不了,维护相对复杂!
-
最佳实践:
-
xml用来管理bean;
-
注解只负责完成属性的注入;
-
使用过程中我们需要注意,要让注解生效,就必须开启注解的支持
<!-- 指定扫描的包,这个包下的注解会生效--> <context:component-scan base-package="com.qijian.pojo"/> <!-- 注解--> <context:annotation-config/>
注意:
使用注解开发时,UerControllerDD user = context.getBean(“uerControllerDD”,UerControllerDD.class);前面的参数(bean的名字)需要最从一定的格式不然就不能够从容器中拿到对应的bean。只需要把该类的第一个字母小写放在其中就可以了。并且如果出现下面的情况那么注入的属性的值时由注解决定的。
@Value("柒间")
private String name = "qijan";
6,使用Java的方式配置Spring
qijianConfig.class
package com.qijian.config;
import com.qijian.dao.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
//这个也会被spring容器托管,注册到容器中,因为它本身就是一个@Conponent
//@Configuration代表这个是一个配置类,就和我们之前的beans.xml
@Configuration
@ComponentScan("com.qijian.dao")
@Import(qijianConfig2.class)//把qijianConfig2配置类导入
public class qijianConfig {
//注册一个bean,相当于我们之前的bean标签
// 这个方法的名字,就相当于bean标签的id属性
// 这个方法的返回值,就相当于bean标签中的class属性
@Bean
public User getUser(){
return new User();//返回注入到bean的对象
}
}
qijianConfig.class
package com.qijian.config;
public class qijianConfig2 {
}
User.class
package com.qijian.dao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//这里这个注解的意思就是说明这个类被spring接管了,注册到了容器中
@Component
public class User {
private String name ;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
@Value("qijian")
public void setName(String name) {
this.name = name;
}
}
MyTest.class
import com.qijian.config.qijianConfig;
import com.qijian.dao.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
@Test
public void Test1(){
//如果完全使用了配置类方式去做,我们只能通过AnnotationConfig上下文来获取容器,通过配置文件获取class对象加载
ApplicationContext context = new AnnotationConfigApplicationContext(qijianConfig.class);
User user = context.getBean("getUser", User.class);
System.out.println(user.toString());
}
}
7,代理模式
角色分析
-
抽象角色:一般会用接口或者抽象类来解决
-
真实角色:被代理的角色
-
代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
-
客户:访问代理对象的人
代码步骤:
-
接口
public interface Rent { public void rent(); }
真实角色:
public class Host implements Rent {
public void rent() {
System.out.println("出租房子");
}
}
-
代理角色:
public class Proxy { private Host host; public Proxy(){} public Proxy(Host host){ this.host=host; } public void rent(){ seeHouse(); host.rent(); heTong(); fare(); } //看房 public void seeHouse(){ System.out.println("中介看房"); } // public void heTong(){ System.out.println("签订和同"); } //收中介费 public void fare(){ System.out.println("收中介费"); } }
-
客户段访问代理角色
public class Client { public static void main(String[] args) { //房东出租房子 Host host = new Host(); // 代理,中介帮房东出租,代理角色一般会有些附属操作! Proxy proxy = new Proxy(host); //不用面对房东直接找中介,租房就可以了 proxy.rent(); } }
代理模式的好处:
- 可以使真实角色的操作更加纯粹!不用区关注一些公共业务
- 公共业务交给代理角色!实现了业务的分工!
- 公共业务发生拓展的时候,方便集中管理!
缺点:
- 一个真实的角色就会产生一个代理的角色;代码量会翻倍~开发效率变慢