Spring实现Ioc的多种方式--控制反转、依赖注入、xml配置的方式实现IoC、对象作用域
Spring实现Ioc的多种方式
一、IoC基础
1.1、概念:
1、IoC 控制反转(Inversion of Control)
IoC是一种设计思想。
2、DI 依赖注入
依赖注入是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法
没有IoC的程序中我们使用面向对象编程对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,所谓的控制反转就是:获得依赖对象的方式反转了。
IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版的spring也可以零配置实现IoC。spring容器在初始化时先读取配置文件,根据配置文件或元数据创建对象存入容器中,程序使用时再从IoC容器中取出需要的对象。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息 直接以注解的形式定义在实现类中,从而达到了零配置的目的。
二、使用XML配置的方式实现IoC
2.0、先创建一个maven项目
2.1、Maven项目的pom.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhangneng</groupId><!--组织名-->
<artifactId>springProject</artifactId><!--项目名-->
<version>1.0-SNAPSHOT</version><!--版本号-->
<packaging>jar</packaging>
<name>Spring051</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.3.0.RELEASE</spring.version>
</properties>
<dependencies>
<!--下面是本项目的依赖jar包 去这个网站:http://mvnrepository.com-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!--如果要全局使用则删掉下面这句-->
<!--
<scope>test</scope>
-->
<version>4.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version><!--一赖上文中的version-->
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>
</dependencies>
</project>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.2、常规的
2.2.1、IBookDao.java
package spring02; /**图书数据访问接口*/
public interface IBookDao {
/**添加新书*/
void save(String name);
}
2.2.2、MySQLBookDao.java
package spring02;
/**接口的实现类*/
public class MySQLBookDao implements IBookDao {
public void save(String name){
System.out.println("添加图书"+name+"到MySQL数据库成功!");
}
}
2.2.3、OracleBookDao.java
package spring02;
/**接口的实现类*/
public class OracleBookDao implements IBookDao {
public void save(String name){
System.out.println("添加图书"+name+"到Oracle数据库成功!");
}
}
2.2.4、BookService.java
package spring02; public class BookService {
IBookDao bookDao;
public BookService(){
bookDao = new MySQLBookDao();
//bookDao = new OracleBookDao();
}
/**新增一本书*/
public void addNewBook(){
String bookname="《Spring MVC学习指南》";
bookDao.save(bookname);
}
}
2.2.5、测试类 BookServiceTest.java
package spring02; import org.junit.Test; import static org.junit.Assert.*; /**不用配置文件实现spring01里的效果,通过改变BookService中的BookService()方法实现*/
/**这样的弊端就是当代码部署到服务器上之后就不能进行控制了,所以我们弄了spring01的方式,通过配置文件来控制使用哪种数据库*/
public class BookServiceTest {
BookService service = new BookService();
@Test
public void addNewBook() throws Exception {
service.addNewBook();
} }
2.2.6、效果:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.3、使用无参构造方法创建对象
2.3.1、IBookDao.java
package spring01; /**图书数据访问接口*/
public interface IBookDao {
/**添加新书*/
void save(String name);
}
2.3.2、MySQLBookDao.java
package spring01;
/**IBookDao的实现类*/
public class MySQLBookDao implements IBookDao {
/**保存一本书到MySQL数据库*/
public void save(String name){
/*这里将处理与MySQL数据库连接的业务功能代码*/
System.out.println("添加图书"+name+"到MySQL数据库成功!");
}
}
2.3.3、OracleBookDao.java
package spring01; /**IBookDao的实现类*/
public class OracleBookDao implements IBookDao {
/**保存一本书到Oracle数据库*/
public void save(String name){
/*这里将处理与Oracle数据库连接的业务功能代码*/
System.out.println("添加图书"+name+"到Oracle数据库成功!");
}
}
2.3.4、BookService.java
package spring01; import javafx.application.Application;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class BookService {
/**创建一个IBookDao对象属性bookDao*/
/**bookDao一定要定义成对象类型,只有对象类型才可以接收*/
IBookDao bookDao; /**通过无参构造方法来获取容器*/
public BookService(){
//创建容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("bookiocbean01.xml");
/*
从容器(bookiocbean01.xml)中获得id为bookdao的bean
bookdao来自bookiocbean01.xml中的id属性的值
*/
//通过IBook接口的bookDao属性来接收容器中的接口实现类
//这里使用强转的形式实现,其实这样是不安全的。
bookDao = (IBookDao) ctx.getBean("bookdao");
}
/**新增一本书*/
public void addNewBook(){
String bookname="《Spring MVC学习指南》";
/**将书籍保存*/
/*调用IBookDao对象的save()方法保存一本书*/
bookDao.save(bookname);
}
}
2.3.5、测试类 BookService.java
package spring01; import org.junit.Test; import static org.junit.Assert.*; /**通过配置文件的形式来决定使用哪种数据库*/
public class BookServiceTest {
BookService service = new BookService();
//测试一下BookService中的addNewBook()方法,看是否可以成功添加书籍
@Test
public void addNewBook() throws Exception {
service.addNewBook();
}
}
2.3.6、bookiocbean01.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">
<!--将使用Oracle数据库 实现新增书籍接口的实现类 导入到这个配置文件(容器)中,且id属性值设置为bookdao,然后去BookService中创建这个容器-->
<!--使用无参构造方法-->
<bean id="bookdao" class="spring01.OracleBookDao"></bean>
</beans>
2.3.7、效果:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.4、使用有参构造方法创建对象
2.4.1、Person.java
package spring03;
/**人*/
public abstract class Person {
/**姓名*/
public String name;
}
2.4.2、Student.java
package spring03; /**学生*/
public class Student extends Person{
/**身高*/
public int height;
/**有参构造方法*/
public Student(String name,int height){
this.name=name;
this.height=height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", height=" + height +
'}';
}
}
2.4.3、Person.java
package spring03; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class School {
public static void main(String[] args) {
//ioc容器
ApplicationContext ctx =
new ClassPathXmlApplicationContext("beans02.xml","bookiocbean01.xml");
//从容器中获取对象
Person tom = ctx.getBean("tom",Person.class);
System.out.println(tom);
}
}
2.4.4、beans02.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="tom" class="spring03.Student">
<constructor-arg name="name" value="张百川"></constructor-arg>
<constructor-arg name="height" value="195"></constructor-arg>
</bean>
</beans>
2.4.5、运行结果:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.5、使用有参构造方法创建对象
2.5.1、person.java
package spring04; /**人*/
public abstract class Person {
/**姓名*/
public String name;
/**地址*/
public Address address;
}
2.5.2、Student.java
package spring04; /**
* Created by Admin on 2017/11/6.
*/ /**学生*/
public class Student extends Person {
/**身高*/
public int height;
/**有参构造方法*/
public Student(String name,int height){
this.name=name;
this.height=height;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", height=" + height +
'}';
}
}
2.5.3、Address.java
package spring04; /**
* Created by Admin on 2017/11/6.
*/
/**地址*/
public class Address {
/**国家*/
private String country;
/**城市 */
private String city; public Address() {
} public Address(String country, String city) {
this.country = country;
this.city = city;
} public String getCountry() {
return country;
} public void setCountry(String country) {
this.country = country;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
} @Override
public String toString() {
return "Address{" +
"country='" + country + '\'' +
", city='" + city + '\'' +
'}';
}
}
2.5.4、School.java
package spring04; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class School {
public static void main(String[] args) {
//ioc容器
ApplicationContext ctx =
new ClassPathXmlApplicationContext("beans03.xml","bookiocbean01.xml");
//从容器中获取对象
Person rose = ctx.getBean("rose", Person.class);
System.out.println(rose);
}
}
2.5.5、beans03.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="rose" class="spring04.Student">
<constructor-arg index="0" value="张柏芝"></constructor-arg>
<constructor-arg index="1" value="196"></constructor-arg>
</bean> </beans>
2.5.6、运行效果
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.6、通过属性赋值创建对象
2.6.1、Person.java
package spring05; /**人*/
public abstract class Person {
/**姓名*/
public String name;
}
2.6.2、Student.java
package spring05; /**学生*/
public class Student extends Person {
/**身高*/
public int height;
/**有参构造方法*/
public Student(String name,int height){
this.name=name;
this.height=height;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", height=" + height +
'}';
}
}
2.6.3、School.java
package spring05; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class School {
public static void main(String[] args) { //ioc容器
ApplicationContext ctx =
new ClassPathXmlApplicationContext("beans04.xml","bookiocbean01.xml");
//从容器中获取对象
Person rose = ctx.getBean("rose",Person.class);
Address zhuhai = ctx.getBean("zhuhai",Address.class);
System.out.println(zhuhai);
System.out.println(rose);
}
}
2.6.4、beans04.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="rose" class="spring05.Student">
<constructor-arg index="0" value="张柏芝"></constructor-arg>
<constructor-arg index="1" value="196"></constructor-arg>
</bean>
<bean name="zhuhai" class="spring05.Address">
<property name="country" value="中国"></property>
<property name="city" value="珠海"></property>
</bean>
</beans>
2.6.5、运行效果:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.7、使用对象引用的方式创建对象
2.7.1、Person.java
package spring06; /**人*/
public abstract class Person {
/**姓名*/
public String name;
/**地址*/
public Address address; 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;
}
}
2.7.2、Student.java
package spring06; /**学生*/
public class Student extends Person {
/**身高*/
public int height; /**有参构造方法*/
public Student(String name,int height){
this.name=name;
this.height=height;
}
/**有参构造方法*/
public Student(String name,int height,Address address){
this.name=name;
this.height=height;
this.address=address;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", height=" + height +
'}'+address;
}
}
2.7.3、Address.java
package spring06; /**地址*/
public class Address {
/**国家*/
private String country;
/**城市 */
private String city; public Address() {
} public Address(String country, String city) {
this.country = country;
this.city = city;
} public String getCountry() {
return country;
} public void setCountry(String country) {
this.country = country;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
} @Override
public String toString() {
return "Address{" +
"country='" + country + '\'' +
", city='" + city + '\'' +
'}';
}
}
2.7.4、School.java
package spring06; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class School {
public static void main(String[] args) {
/**ioc容器*/
ApplicationContext ctx =
new ClassPathXmlApplicationContext("beans05.xml","bookiocbean01.xml");
//从容器中获取对象
Person tom = ctx.getBean("tom",Person.class);
Person rose = ctx.getBean("rose",Person.class);
//Address zhuhai = ctx.getBean("zhuhai", Address.class);
System.out.println(tom);
System.out.println(rose);
}
}
2.7.5、beans05.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">
<!--可以使用id或(和)name属性来指定bean的标识符-->
<bean name="zhuhai" class="spring06.Address">
<property name="country" value="中国"></property>
<property name="city" value="珠海"></property>
</bean>
<bean id="tom" class="spring06.Student">
<constructor-arg name="name" value="张柏川"></constructor-arg>
<constructor-arg name="height" value="195"></constructor-arg>
<constructor-arg name="address" ref="zhuhai"></constructor-arg>
</bean>
<bean id="rose" class="spring06.Student">
<constructor-arg index="0" value="张柏芝"></constructor-arg>
<constructor-arg index="1" value="196"></constructor-arg>
<constructor-arg index="2" ref="zhuhai"></constructor-arg>
</bean>
</beans>
2.7.6、运行结果:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.8、对象的作用域--使用scope属性可以指定作用域
2.8.1、从容器中取回的对象默认是单例的:
将2.7的实例中的School.java类的代码改为下列代码则可以验证其默认为单例模式:
package spring06; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class School {
public static void main(String[] args) {
/**ioc容器*/
ApplicationContext ctx =
new ClassPathXmlApplicationContext("beans05.xml","bookiocbean01.xml");
//从容器中获取对象
Person rose1 = ctx.getBean("rose",Person.class);
Person rose2 = ctx.getBean("rose",Person.class); System.out.println(rose1==rose2);//这句代码输出的结果为true证明默认为单例模式
System.out.println(rose1!=rose2);
}
}
2.8.2、作用域(使用scope属性可以指定作用域)
用scope="prototype"给一个Bean定义多个对象实例的示例:
1、将2.7示例中的beans05.xml中的内容改为如下代码:
<bean id="rose" class="spring02.Student" scope="prototype">
<constructor-arg index="0" value="张柏芝"></constructor-arg>
<constructor-arg index="1" value="196"></constructor-arg>
<constructor-arg index="2" ref="zhuhai"></constructor-arg>
</bean>
2、将2.7示例中的School.java类中的代码改为如下代码:
package spring06; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class School {
public static void main(String[] args) {
/**ioc容器*/
ApplicationContext ctx =
new ClassPathXmlApplicationContext("beans05.xml","bookiocbean01.xml");
//从容器中获取对象
Person tom=ctx.getBean("tom",Person.class);
Person roseA=ctx.getBean("rose",Person.class);
Person roseB=ctx.getBean("rose",Person.class);
//Address zhuhai=ctx.getBean("zhuhai",Address.class);
System.out.println(tom);
System.out.println(roseA==roseB);
}
}
3、运行结果如下: --从结果为false可以看出它不再是单例,而是多实例。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.9、延迟初始化Bean
ApplicationContext
实现的默认行为就是再启动时将所有 singleton bean提前进行实例化。 通常这样的提前实例化方式是好事,因为配置中或者运行环境的错误就会被立刻发现,否则可能要花几个小时甚至几天。如果你不想 这样,你可以将单例bean定义为延迟加载防止它提前实例化。延迟初始化bean会告诉Ioc容器在第一次需要的时候才实例化而不是在容器启动时就实例化。在XML配置文件中,延迟初始化通过<bean/>
元素的lazy-init
属性进行控制,比如:
<!--延迟加载-->
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
<!--不延迟加载-->
<bean name="not.lazy" class="com.foo.AnotherBean"/>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.0、回调方法
3.0.1、初始化回调函数
配置文件:--将2.7中的配置文件改为下面的样子
<bean id="tom" class="spring02.Student" init-method="init" destroy-method="over">
<constructor-arg name="name" value="张柏川"></constructor-arg>
<constructor-arg name="height" value="195"></constructor-arg>
<constructor-arg name="address" ref="zhuhai"></constructor-arg>
</bean>
Student类: --将2.7中的student类改为下面的样子
package spring02; import java.io.File; /**学生*/
public class Student extends Person {
/**身高*/
public int height;
/**有参构造方法*/
public Student(String name,int height){
this.name=name;
this.height=height;
}
/**有参构造方法*/
public Student(String name,int height,Address address){
this.name=name;
this.height=height;
this.address=address;
}
@Override
public String toString() {
return "Student{" + "height=" + height+",name="+name +'}'+address;
} public void init(){
System.out.println("对象被创建");
}
public void over(){
System.out.println("对象被回收");
} }
运行结果:
Spring实现Ioc的多种方式--控制反转、依赖注入、xml配置的方式实现IoC、对象作用域的更多相关文章
- Spring IOC - 控制反转(依赖注入) - 入门案例 - 获取对象的方式 - 别名标签
1. IOC - 控制反转(依赖注入) 所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交 由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周 ...
- Spring总结——控制反转,注入(配置和注解两种方式)
一.Spring的容器: 1.什么是控制反转:传统的方法,当某个java对象A需要调用对象B时,是由调用者(对象A)通过new关键字来创建对象B的(也可以说类A依赖类B),而在Spring中,则是由s ...
- 控制反转&依赖注入
IoC(Inversion of Control,控制反转).这是spring的核心,贯穿始终.所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.这是什么 ...
- [PHP] 控制反转依赖注入的日常使用
控制反转:控制权交给了自己的类 依赖注入:依赖另一个类,我没有手动去new它 <?php /*我自己要用的类*/ class User { private $name; private $age ...
- Spring Boot 框架下使用MyBatis访问数据库之基于XML配置的方式
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...
- Spring IOC - 控制反转(依赖注入) - 创建对象的方式
a.通过类的无参构造方法创建对象 在入门案例中就是这种方式.当用最普通的方式配饰一个<bean>时,默认就是采用类的 无参构造创建对象.在Spring容器初始化时,通过<bean&g ...
- 码农小汪-spring框架学习之2-spring IoC and Beans 控制反转 依赖注入 ApplicationContext BeanFactory
spring Ioc依赖注入控制反转 事实上这个东西很好理解的,并非那么的复杂. 当某个Java对象,须要调用还有一个Java对象的时候(被依赖的对象)的方法时.曾经我们的做法是怎么做呢?主动的去创建 ...
- Spring IOC - 控制反转(依赖注入) - 懒加载机制
懒加载机制 Spring默认会在容器初始化的过程中,解析xml,并将单例的bean创建并保存到map中,这样的机制在bean比较少的时间问题不大,但一旦bean非常多时,Spring需要在启动的过程中 ...
- Spring框架使用(控制反转,依赖注入,面向切面AOP)
参见:http://blog.csdn.net/fei641327936/article/details/52015121 Mybatis: 实现IOC的轻量级的一个Bean的容器 Inversion ...
- 玩转Spring MVC (一)---控制反转(依赖注入)
Spring的核心是控制反转,什么是控制反转呢?小编浅述一下自己的拙见,有不当之处还希望大家指出. 控制反转(IOC),也可以叫做依赖注入(DI),这两个词其实是一个概念. 控制反转,那是什么控制被反 ...
随机推荐
- 最简单的TTcpServer与TTcpClient通信实例-Delphi
unit TcpSCDemo;//最简单的TTcpServer与TTcpClient通信实例-Delphi //Borland推出TTcpServer与TTcpClient作为主要的网络通信控件,意味 ...
- 扩大了一个逻辑卷,resize2fs 保错:没有这个超级块
检查发现,文件系统类型是xfs,应该使用 xfs_growfs命令刷新文件系统
- Django使用admin管理后台管理数据库表
1.在admin.py文件中注册需要创建的表,例: from .models import * # Register your models here. admin.site.register(Use ...
- 在Winfrom 中,如何实现combox 的列表自动显示ToolTip提示 ?
//带ToolTip的combox类文件 public class ComboBoxWithTooltip : ComboBox { //tipProperty为显示ToolTip文本的数据源的属性 ...
- 20170921xlVBA_SQL蒸发循环查询2
'ARRAY("1991","1992","1993","1994","1996","19 ...
- 小程序中this和that用法
微信小程序中,在wx.request({});方法调用成功或者失败之后,有时候会需要获取页面初始化数据data的情况,这个时候,如果使用,this.data来获取,会出现获取不到的情况,调试页面也会报 ...
- python 构造函数作用
1. 构造函数的作用 构造函数主要用来在创建对象时完成对对象属性的一些初始化等操作, 当创建对象时, 对象会自动调用它的构造函数.一般来说, 构造函数有以下三个方面的作用: ...
- 女性睾酮水平高(High Testosterone Levels in Women)
在外国网站了解睾酮高的一些资料,顺便记录生活点滴. 摘自网址:https://www.healthline.com/health/high-testosterone-in-women 高睾酮的妇女 睾 ...
- Apache+PHP+MySQL+phpMyAdmin+WordPress搭建
一 .安装Apache 下载地址:http://www.apachelounge.com/download/,选择Apache 2.4.25 Win64,解压缩,修改配置文件中如下地方: 1.Serv ...
- ECharts柱状图添加点击事件
参考: https://zhuanlan.zhihu.com/p/33050579 https://blog.csdn.net/sophia_xiaoma/article/details/780559 ...