文章大纲

一、Spring介绍
二、Spring的IoC实战
三、IoC常见注解总结
四、项目源码及参考资料下载
五、参考文章

一、Spring介绍

1. 什么是Spring

  Spring是分层的Java SE/EE应用 full-stack轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。

2. Spring优势

方便解耦,简化开发
  通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
AOP编程的支持
  通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP(面向对象的程序设计)实现的功能可以通过AOP轻松应付。
声明式事务的支持
  可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
方便程序的测试
  可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
方便集成各种优秀框架
  Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
降低JavaEE API的使用难度
  Spring对JavaEE API(如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。

3. spring的体系结构

 

二、Spring的IOC实战

  控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
  IoC有两种实现方式,一种是配置文件(bean管理)方式,具体包括使用类的无参数构造方法(重点)、使用静态工厂创建、使用实例工厂创建。第二种是注解方式。

1. 创建项目

 

2. 添加jar包(实际开发中使用maven)

将jar包复制到以下文件夹中

 

设置依赖
具体方式可参考博客中地址:https://zyjustin9.iteye.com/blog/2172445

3. 配置文件(bean管理)方式实现

方式一:使用id配置方法--常用(重要)
创建测试类User.java

public class User {

    public void add() {

        System.out.println("add.......");
} public void add(String haha)
{ System.out.println("add.."+haha); }
}

src下创建配置文件myXml.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" > <!--
本来在该配置文件中还有一个属性name,其作用和id一样,id属性值不能包含特殊符号(比如@#),但是name属性可以,不过name属性是很早版本时候使用的,现在都被替换成id了
scope属性,总共有以下的值,但是最主要用的是前两个,后面两个不用记得,在该配置文件中我们没有写scope属性,默认使用的是singleton
singleton:默认值、单例的
prototype:多例的:
request:创建对象,把对象放在request域里面
session:创建对象,把对象放在session域里面
globalSession:创建对象,把对象放在globalSession域里面
--> <!-- 第一种方法:ioc的配置文件 id是类的标志 class是对象类全路径-->
<bean id="user" class="ioc1.User" scope="singleton"/> </beans>

编写测试代码

/**
* 测试配置方式实现IOC三种方法
*
* @author 吴晓畅
*
*/
public class TestIoc { @Test
public void testUser() { //加载spring配置文件,根据内容创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("myXml.xml"); //方法1 :使用id配置方法--常用
User user = (User) context.getBean("user");
System.out.println(user);
user.add("尼玛"); } }

运行结果如下:

 

方式二:静态工厂(了解就好)
创建测试类User2.java

package ioc2;

public class User2 {

    public void add() {

        System.out.println("user2........");
} }

创建测试工厂类User2Factory.java

package ioc2;

public class User2Factory {

    public static User2 getUser2()
{ return new User2(); } }

src下创建配置文件myXml.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" > <!--
本来在该配置文件中还有一个属性name,其作用和id一样,id属性值不能包含特殊符号(比如@#),但是name属性可以,不过name属性是很早版本时候使用的,现在都被替换成id了
scope属性,总共有以下的值,但是最主要用的是前两个,后面两个不用记得,在该配置文件中我们没有写scope属性,默认使用的是singleton
singleton:默认值、单例的
prototype:多例的:
request:创建对象,把对象放在request域里面
session:创建对象,把对象放在session域里面
globalSession:创建对象,把对象放在globalSession域里面
-->
<!-- 第二种方法:使用静态工厂创建对象 -->
<bean id="user2" class="ioc2.User2Factory" factory-method="getUser2"/> </beans>

测试代码如下:

package introduction;

import ioc1.User;
import ioc2.User2;
import ioc3.User3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* 测试配置方式实现IOC三种方法
*
* @author 吴晓畅
*
*/
public class TestIoc { @Test
public void testUser() { //加载spring配置文件,根据内容创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("myXml.xml"); //方法2:使用静态工厂方法--了解就好
User2 user2 = (User2) context.getBean("user2");
System.out.println(user2); } }

运行结果如下:

 

方式三:实例工厂(了解就好)
创建测试类User3.java

package ioc3;

public class User3 {

    public void add() {

        System.out.println("user3........");
} }

创建测试工厂类User3Factory.java

package ioc3;

public class User3Factory {

    //普通方法,返回User3对象
public User3 getUser3()
{ return new User3(); } }

src下创建配置文件myXml.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" > <!--
本来在该配置文件中还有一个属性name,其作用和id一样,id属性值不能包含特殊符号(比如@#),但是name属性可以,不过name属性是很早版本时候使用的,现在都被替换成id了
scope属性,总共有以下的值,但是最主要用的是前两个,后面两个不用记得,在该配置文件中我们没有写scope属性,默认使用的是singleton
singleton:默认值、单例的
prototype:多例的:
request:创建对象,把对象放在request域里面
session:创建对象,把对象放在session域里面
globalSession:创建对象,把对象放在globalSession域里面
--> <!-- 第三种方法:使用实例工厂创建对象 -->
<!-- 创建工厂类的对象 -->
<bean id="User3Factory" class="ioc3.User3Factory"></bean>
<bean id="user3" factory-bean="User3Factory" factory-method="getUser3"></bean> </beans>

测试代码如下:

package introduction;

import ioc3.User3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* 测试配置方式实现IOC三种方法
*
* @author 吴晓畅
*
*/
public class TestIoc { @Test
public void testUser() { //加载spring配置文件,根据内容创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("myXml.xml"); //方法3:使用实例工厂创建对象--了解就好
User3 user3 = (User3) context.getBean("user3");
System.out.println(user3); } }

运行结果如下:

 

4. 注解方式实现

方式一:实现对象创建
创建测试类:UserBean1.java

/**
* 采用注解方式完成ioc
*
* @author 吴晓畅
*
*/
//目前spring有四个注解,功能都是一样的,都是创建对象用的
//@Component @Controller @Service @Repository
@Component(value="userBean1")//这个相当于<bean id="user" class=""/>
public class UserBean1 { public void add() { System.out.println("UserBean1....add"); } }

src下创建配置文件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"
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"> <!-- bean definitions here --> <!--
开启注解扫描 base-package写的包名 如果类在多个包里面,那么写的方式如下
ioc_bean1,ioc_bean2,ioc_bean3...
或者采用cn 这样表示加载cn开头的所有包 cn.ioc则表示加载 cn.ioc开头的所有包
--> <!-- 到包里面扫描类、方法、属性上面注解 -->
<context:component-scan base-package="ioc_bean1"></context:component-scan> <!-- 只扫描属性上面的注解 -->
<!--<context:annotation-config></context:annotation-config> --> </beans>

测试代码如下

package introduction;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import ioc_bean1.UserBean1;
import ioc_bean1.UserService;; /**
* 测试bean方式使用IOC
*
* @author 吴晓畅
*
*/
public class TestBean { @Test
public void testUser() { //加载spring配置文件,根据内容创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); //测试bean配置方式创建对象
UserBean1 userBean1 = (UserBean1) context.getBean("userBean1");
System.out.println(userBean1);
userBean1.add();
} }

运行结果如下

 

方式二:bean配置方式注入对象属性

创建测试类:UserDao.java


import org.springframework.stereotype.Component; //这一步相当于创建了UserDao对象
@Component(value="userDao")
public class UserDao { public void add() { System.out.println("UserDao....add"); } }

编写测试类UserService.java

package ioc_bean1;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; //@Service(value="userService")等同于@Service("userService")
//这一步相当于创建了UserService对象
@Service(value="userService")
public class UserService { //得到UserDao对象 使用注解方式时候不需要使用set方法,直接到UserDao对象上面使用注解,完成对象注入
//即@Autowired用于注入属性
@Autowired
private UserDao userDao; //这种方式与上面方式能达到同样效果 常用的是下面这种
//name的值要与UserDao的注解的value一致
// @Resource(name="userDao")
// private UserDao userDao; public void add() { System.out.println("UserService...add...."); userDao.add(); } }

src下配置方式与方式一一致

测试代码如下:

package introduction;

import ioc_bean1.UserBean1;
import ioc_bean1.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; ; /**
* 测试bean方式使用IOC
*
* @author 吴晓畅
*
*/
public class TestBean { @Test
public void testUser() { //加载spring配置文件,根据内容创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); //测试bean配置方式注入对象属性
UserService userService = (UserService) context.getBean("userService");
userService.add();
} }

运行结果如下

 

温馨提示:
  上面注解方式需要在使用类上面加上@Component(value="userDao"),在对象变量上使用@Autowired才能实现。

方式三:配置文件与注解方式混合使用
创建测试类BookDao.java

package ioc_bean2;

public class BookDao {

    public void book() {

        System.out.println("BookDao....book");

    }

}

创建测试类OrderDao.java

package ioc_bean2;

public class OrderDao {

    public void buy() {

        System.out.println("OrderDao....buy");

    }

}

创建测试服务BookService.java,在该服务中通过注解方式注入对象属性

package ioc_bean2;

import javax.annotation.Resource;

public class BookService {

    //得到BookDao和OrderDao的对象
@Resource(name="bookDao")
private BookDao bookDao;
@Resource(name="orderDao")
private OrderDao orderDao; public void add() { System.out.println("service"); bookDao.book(); orderDao.buy(); } }

src下配置文件如下

<?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"> <!-- bean definitions here --> <!--
开启注解扫描 base-package写的包名 如果类在多个包里面,那么写的方式如下
ioc_bean1,ioc_bean2,ioc_bean3...
或者采用cn 这样表示加载cn开头的所有包 cn.ioc则表示加载 cn.ioc开头的所有包
--> <!-- 到包里面扫描类、方法、属性上面注解 -->
<context:component-scan base-package="ioc_bean2"></context:component-scan> <!-- 配置对象 -->
<bean id="bookService" class="ioc_bean2.BookService"></bean>
<bean id="bookDao" class="ioc_bean2.BookDao"></bean>
<bean id="orderDao" class="ioc_bean2.OrderDao"></bean> </beans>

测试代码如下

package ioc_bean2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import ioc1.User;
import ioc2.User2;
import ioc3.User3; public class TestMixBean { @Test
public void testService() { //加载spring配置文件,根据内容创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); BookService bookService = (BookService) context.getBean("bookService"); bookService.add(); } }

运行结果如下

 

方式四:带参数的属性注入
创建数组、集合、properties属性注入测试类Person.java

package property;

import java.util.List;
import java.util.Map;
import java.util.Properties; /**
* 测试数组、集合、properties属性注入
*
* @author 吴晓畅
*
*/
public class Person { private String pName; private String[] arrs; private List<String> list; private Map<String, String> map; private Properties properties; public void setpName(String pName) {
this.pName = pName;
} public void setArrs(String[] arrs) {
this.arrs = arrs;
} public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
} public void setProperties(Properties properties) {
this.properties = properties;
} public void test1() { System.out.println("pName--"+pName); System.out.println("arrs--"+arrs); System.out.println("list--"+list); System.out.println("map--"+map); System.out.println("properties--"+properties); } }

创建构造方法注入属性测试类PropertyDemo1.java

package property;

/**
* 通过构造方法注入属性
*
* @author 吴晓畅
*
*/
public class PropertyDemo1 { private String userName; public PropertyDemo1(String userName) { this.userName = userName;
} public void test1() { System.out.println("demo1......"+userName); } }

创建set方法注入属性测试类PropertyDemo2.java

package property;

/**
* 通过set方法注入属性
*
* @author 吴晓畅
*
*/
public class PropertyDemo2 { private String bookName; //set方法 该方法一定要符合set/get方法命名规则
public void setBookName(String bookName) {
this.bookName = bookName;
} public void demoBookName()
{ System.out.println("book..."+bookName); } }

对象属性注入测试类UserDao.java

package property;

/**
* 对象属性注入
*
* @author 吴晓畅
*
*/
public class UserDao { public void add() { System.out.println("UserDao.....dao"); }
}

对象属性注入测试类UserService.java

package property;

/**
* 对象属性注入
*
* @author 吴晓畅
*
*/
public class UserService { //定义UserDao属性
private UserDao dao; //定义set方法
public void setDao(UserDao dao) {
this.dao = dao;
} public void add() { System.out.println("UserService...service"); //使用dao对象
dao.add(); } }

src下配置文件myXml.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" > <!--
本来在该配置文件中还有一个属性name,其作用和id一样,id属性值不能包含特殊符号(比如@#),但是name属性可以,不过name属性是很早版本时候使用的,现在都被替换成id了
scope属性,总共有以下的值,但是最主要用的是前两个,后面两个不用记得,在该配置文件中我们没有写scope属性,默认使用的是singleton
singleton:默认值、单例的
prototype:多例的:
request:创建对象,把对象放在request域里面
session:创建对象,把对象放在session域里面
globalSession:创建对象,把对象放在globalSession域里面
--> <!-- 使用有参数构造注入属性 -->
<bean class="property.PropertyDemo1" id="demo">
<!-- 表示给userName属性注入value为小王的值 -->
<constructor-arg value="小王" name="userName"> </constructor-arg>
</bean> <!-- 使用set方法注入属性 -->
<!--这一步相当于创建了 property.PropertyDemo2类的对象-->
<bean class="property.PropertyDemo2" id="demo2">
<!-- 表示给userName属性注入value为小王的值 -->
<property value="易筋经" name="bookName"> </property>
</bean> <!-- 注入对象类型的属性 -->
<!-- 配置UserService和UserDao的对象 -->
<bean id="userDao" class="property.UserDao"></bean>
<bean id="userService" class="property.UserService">
<!-- 注入dao对象 现在不要写value属性,因为上面是字符串,现在是对象,使用ref属性,dao配置bean标签中的id值-->
<property name="dao" ref="userDao"></property>
</bean> <!-- 注入复杂类型属性-》包括数组、集合等 -->
<bean id="person" class="property.Person"> <!-- 数组 -->
<property name="arrs">
<list>
<value>小王</value>
<value>小马</value>
<value>小宋</value>
</list>
</property> <!-- list集合 -->
<property name="list">
<list>
<value>小奥</value>
<value>小金</value>
<value>小普</value>
</list>
</property> <!-- map集合 -->
<property name="map">
<map>
<entry key="aa" value="Lucy"></entry>
<entry key="bb" value="Mary"></entry>
<entry key="cc" value="Tom"></entry>
</map>
</property> <!-- properties -->
<property name="properties">
<props>
<prop key="driverclass">com.mysql.jdbc.Driver</prop>
<prop key="username">root</prop>
</props>
</property>
</bean> </beans>

测试代码如下

package property;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* 测试属性注入
*
* @author 吴晓畅
*
*/
public class TestIoc { @Test
public void textUser() { //加载spring配置文件,根据内容创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("myXml.xml"); //测试构造注入属性的方法
//得到配置创建的对象
PropertyDemo1 demo1 = (PropertyDemo1)context.getBean("demo");
demo1.test1(); //测试set方法注入属性值
PropertyDemo2 demo2 = (PropertyDemo2)context.getBean("demo2");
demo2.demoBookName(); //测试使用set方法注入对象属性
UserService userService = (UserService) context.getBean("userService");
userService.add(); //使用set方法注入复杂属性对象
Person person = (Person) context.getBean("person");
person.test1();
} }

运行结果如下

log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
demo1......小王
book...易筋经
UserService...service
UserDao.....dao
pName--null
arrs--[Ljava.lang.String;@28ac3dc3
list--[小奥, 小金, 小普]
map--{aa=Lucy, bb=Mary, cc=Tom}
properties--{driverclass=com.mysql.jdbc.Driver, username=root} Process finished with exit code 0

三、IoC常见注解总结

  1. 创建对象(相当于:<bean id="" class="">)
    (1)@Component
      作用:把资源让spring来管理。相当于在xml中配置一个bean。
      属性:value:指定bean的id。如果不指定value属性,默认bean的id是当前类的类名。首字母小写。

(2)@Controller @Service @Repository
  他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。
  他们只不过是提供了更加明确的语义化。
  @Controller:一般用于表现层的注解。
  @Service:一般用于业务层的注解。
  @Repository:一般用于持久层的注解。
  细节:如果注解中有且只有一个属性要赋值时,且名称是value,value在赋值是可以不写。

  1. 用于注入数据(相当于:<property name="" ref=""> <property name="" value="">)
    (1)@Autowired
      作用:自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错。
    (2)@Resource
      作用:直接按照Bean的id注入。它也只能注入其他bean类型。
      属性:name:指定bean的id。
    (3)@Value
      作用:注入基本数据类型和String类型数据的
      属性:value:用于指定值

四、项目源码及参考资料下载

链接:https://pan.baidu.com/s/1RDBXQcBchtA9i-bg8Z1r4Q
提取码:io8n

五、参考文章

http://yun.itheima.com/course/215.html?1804lckj

Spring之IoC详解(非原创)的更多相关文章

  1. Redis基础知识详解(非原创)

    文章大纲 一.Redis介绍二.Redis安装并设置开机自动启动三.Redis文件结构四.Redis启动方式五.Redis持久化六.Redis配置文件详解七.Redis图形化工具八.Java之Jedi ...

  2. Spring之IOC详解

    学过Spring的小伙伴对于IOC一定不陌生,IOC:控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spr ...

  3. 搜索引擎框架之ElasticSearch基础详解(非原创)

    文章大纲 一.搜索引擎框架基础介绍二.ElasticSearch的简介三.ElasticSearch安装(Windows版本)四.ElasticSearch操作客户端工具--Kibana五.ES的常用 ...

  4. Java之Spring Boot详解(非原创)

    文章大纲 一.Spring Boot 概述二.Spring Boot 入门案例三.Spring Boot核心功能代码实战四.项目源码与资料下载五.参考文章   一.Spring Boot 概述 1. ...

  5. spring+hibernate实体类注解详解(非原创) + cascade属性取值

    @Entity //继承策略.另一个类继承本类,那么本类里的属性应用到另一个类中 @Inheritance(strategy = InheritanceType.JOINED ) @Table(nam ...

  6. (二)Spring 之IOC 详解

    第一节:spring ioc 简介 IOC(控制反转:Inversion of Control),又称作依赖注入dependency injection( DI ),是一种重要的面向对象编程的法则来削 ...

  7. 权限框架之Shiro详解(非原创)

    文章大纲 一.权限框架介绍二.Shiro基础介绍三.Spring Boot整合Shiro代码实战四.项目源码与资料下载五.参考文章   一.权限框架介绍 1. 什么是权限管理   权限管理属于系统安全 ...

  8. 2、Spring的 IoC详解(第一个Spring程序)

    Spring是为了解决企业应用开发的复杂性而创建的一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.在这句话中重点有两个,一个是IoC,另一个是AOP.今天我们讲第一个IoC. IoC概念 ...

  9. Spring.Net —IOC详解

    一. Spring.net中IOC介绍 1. 什么是IOC,控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中 ...

随机推荐

  1. Linux安装docker(ubuntu16.04和centos7.4)

    ubuntu16.04版本 1.安装依赖 sudo apt-get install apt-transport-https ca-certificates software-properties-co ...

  2. WebSocket协议-基础篇

    本篇文章主要讲述以下几点: WebSocket协议出现的背景 WebSocket与HTTP WebSocket API WebSocket协议出现的背景 我们在上网过程中经常用到的是HTTP和HTTP ...

  3. 微信小程序使用npm安装第三方库

    微信小程序在 2.2.1 版本后增加了对 npm 包加载的支持,使得小程序支持使用 npm 安装第三方包. 之前在微信开发者工具选择“构建npm”会报错“没找到node_modules”目录”,这是因 ...

  4. ISerializable接口

    继承ISerializable接口可以灵活控制序列化过程 格式化器的工作流程:格式化器再序列化一个对象的时候,发现对象继承了ISerializable接口,那它就会忽略掉类型所有的序列化特性,转而调用 ...

  5. js对url进行编码的方法(encodeURI和 encodeURICompoent())

    encodeURI(): 对整个URL进行编码,对应的解码方式:decodeURI() encodeURIComponent() : 对查询字符串进行编码,对应的解码方式:decodeURICompo ...

  6. 洛谷 P4053 [JSOI2007]建筑抢修

    传送门 思路 首先题意比较容易明白: n个建筑需要修复,只能同时修一个建筑,每个建筑修复需要t1时间,且必须在t2时间前修完,否则此建筑报废 问最多能修好多少个建筑 如果一个建筑在规定时间内没有修好的 ...

  7. 京东联盟开发(12)——删除MySQL表中重复记录并且只保留一条

    本文介绍如何删除商品表中的一些重复记录. 有时,一条商品由于有多个skuid,比如某种手机有不同颜色,但价格.优惠等信息却是一致,导致其被多次收录.由于其各种条件基本类似,这样它在商品中多个sku都排 ...

  8. asp.net core 3.0 身份认证 替换为自已的提供程序 AuthenticationStateProvider replace to SelfAuthenticationStateProvider

    public void ConfigureServices(IServiceCollection services) { // 添加身份验证服务 services.AddAuthorizationCo ...

  9. Visual Studio2017专业版和企业版密钥

    Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

  10. Oracle 自定义函数实现列转行效果

    在 Oracle 领域,我相信一说到列转行大部分人都会立马想到 WM_CONCAT 函数,我觉得主要是因为该函数比较实用.但事实上 WM_CONCAT 并非官方公开函数,使用会存在一定的风险:函数返回 ...