Spring: (一) -- 春雨潤物之 核心IOC

  作為一個Java人,想必都或多或少的了解過Spring。對于其優勢也能道個一二,諸如方便解耦、支持AOP編程、支持聲明式事務、方便測試等等。Spring也不僅僅局限于服務器端開發,它可以做非常多的事情,任何Java應用都可以在簡單性、可測試性和松耦合等方面從Spring中受益。Spring豐富功能的底層都依賴于它的兩個核心特性:

  • 控制反轉 IOC (Inversion Of Control)

  • 面向切面編程 AOP (Aspect-Oriented Programming)

控制反轉指的是應用中的對象依賴關系不在由自己維護,而交給Spring由它的容器幫我們維護,因此也叫做依賴注入DI (Dependency Injection)。

一.使用BeanFactory解耦

?這里使用BeanFactory來降低我們熟知的MVC編程模式中service層與dao層之間的耦合關系。

解耦前(service層關鍵代碼)

// Service層中需要Dao層的實例來與數據庫交互完成業務邏輯
public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImpl();public void registerUser(User user) {userDao.addUser(user);}

可以看出,如果我們不做解耦操作,那么Service層中強烈依賴UserDao的實現類UserDaoImpl(即如果不new UserDaoImpl(),Service層將寸步難行)。

解耦后(service層關鍵代碼)

public class UserServiceImpl implements UserService {private UserDao userDao;// 提供set方法public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void registerUser(User user) {userDao.addUser(user);}

BeanFactory

public class BeanFactory {private static Map<String, Object> beans = new HashMap<String, Object>();//靜態代碼塊加載資源static {try {ResourceBundle bundle = ResourceBundle.getBundle("objects");Enumeration<String> keys = bundle.getKeys();while (keys.hasMoreElements()) {String key = keys.nextElement();String className = bundle.getString(key);Object clazz = Class.forName(className).newInstance();beans.put(key, clazz);}} catch (Exception e) {e.printStackTrace();throw new RuntimeException("加載類配置文件出錯!");}}//對外提供獲取bean的方法public static <T> T getBean(String className, Class<T> T) {Object o = beans.get(className);if (o != null)return (T) o;else throw new RuntimeException("找不到類:" + className);}
}

objects.properties

userDao=com.dintalk.dao.impl.UserDaoImpl

為UserServiceImpl實例注入依賴

UserServiceImpl userServiceImpl = new UserServiceImpl();
UserDao userDao = BeanFactory.getBean("userDao",UserDao.class);
userServiceImpl.setUserDao(userDao);

總結:

?   解耦前,service層中直接new出了其所依賴的實例對象userDaoImpl。而通過工廠解耦后,service中只聲明了UserDao的接口引用,并提供了set方法,我們在使用servcie時,可以通過set方法傳入從工廠中獲得的實現了UserDao接口的任一實現類的實例。而實現類的配置又暴露在了配置文件當中,解耦的同時也增加了程序的動態性。

BeanFactory原理:

?   這里使用的是靜態工廠,在工廠類中定義了一個Map用于存放工廠管理的Bean實例,靜態代碼塊隨類的加載執行一次,讀取配置文件中的key-value信息。通過循環和反射,將配置文件中的key仍作為Map的key;將配置文件中key對應的類全限定名通過反射構造實例后作為其對應的value存于Map中。達到這樣的效果:BeanFactory類加載完畢后,它便管理了一個Map集合,Map集合的key就是配置文件中的key,Map中的value就是配置文件中value對應的類的實例。如此,對外提供一個getBean方法,通過key返回其對應的實例,這便實現了通過BeanFactory來管理實例對象。

二.Spring使用步驟

以使用xml配置文件的方式示例:

1.導入坐標或jar包

? 如果使用Maven構建,我們可以導入spring-context。因為上下文模塊依賴其他模塊,所有其他模塊也會自動導入。

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version>
</dependency>

2.創建applicationContext.xml文件并加入頭信息

? 在resources下創建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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean>...</bean><!-- 1.主配置文件中導入模塊配置文件 --><import resource="user.xml"/>
</beans>

3.在配置文件中裝配Bean并加載配置文件獲取Bean

? 可以按分模塊在配置文件中裝配Bean,再在主配置文件中進行導入。但要注意,如果出現id相同的情況,后加載的配置會覆蓋掉前面的配置!

加載配置文件獲取Bean

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = appContext.getBean("userDao", UserDao.class);

Tips: Spring有自己的容器,需要讀取配置文件裝配好Bean后放入自己的容器,我們在用時直接找容器獲取即可!如果分模塊配置了但沒有在主文件中導入其他文件也可以在加載配置文件時一塊加載:

ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml","user.xml"});

三.IOC配置(Bean的裝配方式)

?   Spring的一大特點是最小侵入性編程,它不會強迫我們去實現它的接口或實現類,POJO依舊是那個POJO。我們只是將依賴交由Spring管理,因此,IOC配置也就是Bean的裝配便是很大一部分工作。Spring為我們提供了三種裝配Bean的方式:

  • 基于xml配置文件 ★★★★

  • 基于注解(往往配合xml配置文件使用) ★★★★

  • 基于java類的配置(會用到注解)

其實,無論使用哪一種方式,我們的目的只有一個,那就是我們要將程序中的依賴關系描述清楚,將Bean裝配好交由Spring的容器!

1.基于xml文件的裝配

bean的實例化

<!-- 0.通過默認構造方法生產bean -->
<bean id="userDao" class="cn.dintalk.dao.impl.UserDaoImpl"></bean>
<!-- 1.通過實例工廠生產bean -->
<bean id="myBeanFactory" class="cn.dintalk.factory.BeanFactory1"/>
<bean id="myBean" factory-bean="myBeanFactory" factory-method="getBean">
<!-- 2.通過靜態工廠生產bean -->
<bean id="userDao1" class="cn.dintalk.factory.BeanFactory" factory-method="getBean"/><!-- bean的存活范圍及生命周期方法 -->
<bean id="userDao2" scope="singleton" init-method="m1" destroy-method="m2" 
class="cn.dintalk.dao.impl.UserDaoImpl"></bean>  

Tips: scope可選值:

  • singleton

  • prototype

  • request

  • session

  • globalsession

    生命周期方法在單例模式下才有意義,想想是為什么呢?

數據的注入

<!-- 3.數據的注入 -->
<!-- 3.1構造方法注入 -->
<bean id="user" class="cn.dintalk.domain.User"><constructor-arg index="0" value="王舞"/><constructor-arg index="1" value="wangwu"/>
</bean>
<!-- 3.2setter屬性注入 -->
<bean id="user1" class="cn.dintalk.domain.User"><property name="name" value="趙思"/><property name="password" value="zhaosi"/>
</bean>
<!-- 3.3p命名空間注入 -->
<bean id="user2" class="cn.dintalk.domain.User" p:name="張珊" p:password="zhangshan"/><!-- 4.常用數據類型的注入 -->
<bean id="user3" class="cn.dintalk.domain.User"><!-- 4.0數組的注入 --><property name="myArr"><array><value>str1</value><value>str2</value></array></property><!-- 4.1List的注入 --><property name="myList"><list><value>str1</value><value>str2</value></list></property><!-- 4.2Set的注入 --><property name="mySet"><set><value>str1</value><value>str2</value></set></property><!-- 4.3Map的注入--><property name="myMap"><map><entry key="s1" value="str1"/><entry key="s2" value="str2"/></map></property><!-- 4.4Properties的注入 --><property name="myPro"><props><prop key="s1">str1</prop><prop key="s2">str2</prop></props></property>
</bean><!-- 5.依賴的注入-->
<bean id="userService" class="cn.dintalk.service.impl.UserServiceImpl"><property name="userDao" ref="userDao"></property>
</bean>

2.基于注解的裝配

?   使用注解來裝配bean可以簡化我們的步驟,提高效率。可以替代xml文件的裝配方式,但是一般是和xml文件的方式打雙打。使用第三方工具包時使用xml的方式要方便一些,章節末我們通過DButil的示例。由于xml的方式比較好理解,而注解又是xml文件方式的簡化,因此我們對比著來學習。

bean的實例化

@Component("accountService")
public class AccountServiceImpl implements AccountService{
/*
- @Controller      用在表現層
- @Service          用在業務層
- @Respository      用在持久層    
這三個注解的作用和@Component完全一樣,就是更加語義化(分層)
*/
// bean的存活范圍和生命周期
@Component("accountService")
@Scope("singleton")
public class AccountServiceImpl implements AccountService {
// 初始化方法
@PostConstruct
private void init(){
// 銷毀方法  
@PreDestroy
private void destroy(){

數據的注入

@Autowired
@Qualifier("accountDao")
private AccountDao accountDao;
/*
- @Autowired   自動裝配,查找Spring容器按照類型自動賦予對象。★★★    
- @Qualifier("accountDao") 與@Autowired配合,指定具體名稱的實現類對象。★★★ 
- @Resource(name="accountDao") Spring對JSR-250中定義的注解的支持。
*/
// - @Value 注入簡單類型的數據
@Value("16")    // 值都是字符串類型,spring會自行解析
private Integer age;
@Value("張珊")
private String name;

基于注解的簡單類型(基本類型+String)數據注入意義不是很大,都在源碼里面,和直接賦值區別不大。

基于注解的配置加載(獲取容器對象)

方式一:依舊使用ClassPathXmlApplicationContext(需配置)★★★

<!-- 配置文件中,指定掃描注解的包 -->
<context:component-scan base-package="cn.dintalk"/>

方式二:使用AnnotationConfigApplicationContext加載配置,獲取bean

ApplicationContext context = new AnnotationConfigApplicationContext(MyBean.class);MyBean myBean = context.getBean("myBean", MyBean.class);

Tips: 我一般使用方式一的配置,但是要注意不要引錯了頭約束。

3.基于java類的裝配

?   基于注解的通過組件掃描和自動裝配實現Spring的自動化配置是更為推薦的方式,但有時候自動化配置的方案行不通,因此需要明確配置Spring。同樣比如,我們想將第三方庫中的組件裝配到我們的應用中,這種情況下,沒有辦法在它的類上添加@Component和@Autowired注解的。因此我們必須采用顯示裝配的方式,顯示裝配有兩種可選方案:上述的xml裝配方式和我們即將闡述的Java類的裝配方式。還是那一句話,無論是哪一種方式,目的只有一個,那就是將一些必要的信息告知我們的程序。

bean的實例化

@Configuration   //Spring配置類,帶有Configuratio注解就是配置類.加不加無所謂
@ComponentScan("cn.dintalk")  //<context:component-scan base-package="cn.dintalk"/>
@Import({JdbcConfig.class,MailConfig.class})  //聚合多個配置類<import resource=""/>
public class SpringConfig {/*
@Configuration可不加:因為我們在加載配置時還會指定到該類- ApplicationContext applicationContext =new AnnotationConfigApplicationContext(SpringConfig.class);
*/@PropertySource("jdbc.properties")//導入外部的properties文件
public class JdbcConfig {//讀取properties文件中key對應的value值@Value("${jdbc.driverClassName}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;//創建數據源//告知spring容器,將該方法的返回值對象,以“druidDataSource”存放到容器中@Bean("druidDataSource")public DataSource createDataSource(){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}//創建QueryRunner對象,并交給spring容器管理@Bean("queryRunner")//@Qualifier("druidDataSource") DataSource dataSource://數據源對象對應spring容器中一個名字叫做druidDataSource的public QueryRunner createQueryRunner(@Qualifier("druidDataSource") DataSource dataSource){QueryRunner queryRunner = new QueryRunner(dataSource);return queryRunner;}

數據的注入

參考同基于注解的裝配

基于java類的配置加載

//AnnotationConfigApplicationContext構造參數:指定配置類的類型
//可以指定多個
ApplicationContext applicationContext =new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = applicationContext.getBean("userService", UserService.class);

四.DBUtils的使用

? DBUtils是Apache提供的對JDBC封裝了的公共組件。

1.普通的使用

第一步:導入jar包或Maven坐標

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.7</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.14</version></dependency>

第二步:創建工具類

public class DruidUtil {private static DataSource dataSource;static {InputStream inputStream = null;try {inputStream = DruidUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");Properties properties = new Properties();properties.load(inputStream);dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();throw new RuntimeException("加載數據庫配置文件失敗!");}finally {if (inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();throw new RuntimeException("關閉文件資源失敗!");}}}}public static DataSource getDataSource(){ // 獲取數據源return dataSource;}public Connection getConnection(){ // 獲取連接try {return dataSource.getConnection();} catch (SQLException e) {e.printStackTrace();throw new RuntimeException(e);}}
}

第三步:CRUD操作(DAO層)

private QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
// 增刪改: 使用update(sql,params);
//update方法內部:先從給定的數據源獲取一個連接,在方法即將執行完畢后,將連接歸還(到連接池)
public void addAccount(Account account) {if (account == null)throw new RuntimeException("參數錯誤");try {queryRunner.update("insert into accounts values(null,?,?)",account.getAccountName(), account.getBalance());} catch (SQLException e) {throw new RuntimeException(e);}}
//查詢:使用 query(sql,Handler,params)public Account findById(Integer aid) {if (aid == null)throw new RuntimeException("參數異常");try {return queryRunner.query("select * from accounts where aid = ?", newBeanHandler<Account>(Account.class), aid);} catch (SQLException e) {throw new RuntimeException(e);}}

2.使用Spring基于xml進行解耦

第一步:導入Spring的jar包或Maven坐標

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version>
</dependency>

第二步:創建applicationContext.xml文件并進行配置

<!-- 1.配置druid數據源 -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring02"/><property name="username" value="sh"/><property name="password" value="sh123"/>
</bean>
<!-- 2.配置QueryRunner -->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner"><constructor-arg index="0" ref="druidDataSource"/>
</bean>
<!-- 3.配置AccountDao -->
<bean id="accountDao" class="cn.dintalk.dao.impl.AccountDaoImpl"><property name="queryRunner" ref="queryRunner"/>
</bean>
<!-- 4.配置AccountService -->
<bean id="accountService" class="cn.dintalk.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/>
</bean>

第三步:CRUD操作

//DAO層 提供set方法以注入
private QueryRunner queryRunner;
public void setQueryRunner(QueryRunner queryRunner) {this.queryRunner = queryRunner;
}//service層 提供set方法以注入
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;
}//CRUD操作同上

Tips: 配置加載方式

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");

3.使用Spring基于注解進行解耦

由于使用到第三方包,所以無法全部使用注解,需要和xml的方式結合。

第一步:配置applicationContext文件

<!-- 1.基于注解,聲明掃描注解的包 -->
<context:component-scan base-package="cn.dintalk"/>
<!-- 2.配置druid數據源 -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring02"/><property name="username" value="sh"/><property name="password" value="sh123"/>
</bean>
<!-- 3.配置QueryRunner -->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner"><constructor-arg index="0" ref="druidDataSource"/>
</bean>

第二步:添加注解

// DAO層中
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {@Autowiredprivate QueryRunner queryRunner;// Service層中
@Service("accountService")
public class AccountServiceImpl implements AccountService {@Autowired@Qualifier("accountDao")private AccountDao accountDao;

第三步:CRUD操作參上

Tips: 配置加載方式

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");

4.使用Spring基于Java類進行解耦

第一步:創建配置類

@PropertySource("jdbc.properties")//導入外部的properties文件
@ComponentScan("cn.dintalk")  // 添加注解掃描包
public class SpringConfig {//讀取properties文件中key對應的value值@Value("${jdbc.driverClassName}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;//創建數據源@Bean("druidDataSource")public DataSource createDataSource(){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}//創建QueryRunner對象,并交給spring容器管理@Bean("queryRunner")//@Qualifier("druidDataSource") DataSource dataSource:
    數據源對象對應spring容器中一個名字叫做druidDataSource的public QueryRunner createQueryRunner(@Qualifier("druidDataSource") DataSource dataSource){QueryRunner queryRunner = new QueryRunner(dataSource);return queryRunner;}

第二步:添加注解

// DAO層中
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {@Autowiredprivate QueryRunner queryRunner;// Service層中
@Service("accountService")
public class AccountServiceImpl implements AccountService {@Autowired@Qualifier("accountDao")private AccountDao accountDao;

第三步:CRUD參上

Tips: 配置加載方式

ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

V.附錄:常用文件約束頭

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

帶有p命名空間的約束頭

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

帶有context命名空間的約束頭

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">
</beans>

?

?

關注微信公眾號,隨時隨地學習

轉載于:https://www.cnblogs.com/dintalk/p/10880873.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/393535.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/393535.shtml
英文地址,請注明出處:http://en.pswp.cn/news/393535.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

reactjs快速如夢_幫助您理解和創建ReactJS應用的快速指南

reactjs快速如夢此帖子分為2部分 (This Post is divided into 2 parts) The First Part demonstrates how to create a simple React app using ‘create-react-app’ CLI and explains the project structure. 第一部分演示了如何使用“ create-react-app” CLI創建簡單的Reac…

leetcode1351. 統計有序矩陣中的負數(二分查找)

給你一個 m * n 的矩陣 grid&#xff0c;矩陣中的元素無論是按行還是按列&#xff0c;都以非遞增順序排列。 請你統計并返回 grid 中 負數 的數目。 示例 1&#xff1a; 輸入&#xff1a;grid [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]] 輸出&#xff1a;8 解釋&a…

XUbuntu22.04之跨平臺音頻編輯工具(平替Audition):ocenaudio(二百零二)

加粗樣式 簡介&#xff1a; CSDN博客專家&#xff0c;專注Android/Linux系統&#xff0c;分享多mic語音方案、音視頻、編解碼等技術&#xff0c;與大家一起成長&#xff01; 優質專欄&#xff1a;Audio工程師進階系列【原創干貨持續更新中……】&#x1f680; 優質專欄&#…

QueryList4采集-圖片本地化

QueryList4采集圖片本地化 //采集public function cai() {//采集的url地址$data QueryList::get(https://news.ke.com/sh/baike/0033/)->rules([title > [.LOGCLICK , text],content > [.summary , text],image > [.lj-lazy , data-original , ,function($res){//…

mysql 從服務器同步設置_mysql主從同步配置

1.為什么要主從同步&#xff1f;在Web應用系統中&#xff0c;數據庫性能是導致系統性能瓶頸最主要的原因之一。尤其是在大規模系統中&#xff0c;數據庫集群已經成為必備的配置之一。集群的好處主要有&#xff1a;查詢負載、數據庫復制備份等。其中Master負責寫操作的負載&…

int、long、long long取值范圍

short int 1個字節儲存 unsigned short int 0&#xff5e;255short int -128&#xff5e;127 int 2個字節儲存 unsigned int 0&#xff5e;4294967295 int 2147483648&#xff5e;2147483647 long 4個字節儲存 unsigned long 0&#xff5e;4294967295long 21…

每天一個LINUX命令(pwd)

每天一個LINUX命令&#xff08;pwd&#xff09; 基本信息 pwd: /bin/pwd&#xff0c;顯示當前路徑的絕對路徑 語法&#xff1a;pwd 應用程序位置 which pwd PWD作用 pwd --help或者man pwd PWD的使用 pwd 轉載于:https://www.cnblogs.com/shanshanliu/p/6542403.html

leetcode69. x 的平方根(二分法)

實現 int sqrt(int x) 函數。 計算并返回 x 的平方根&#xff0c;其中 x 是非負整數。 由于返回類型是整數&#xff0c;結果只保留整數的部分&#xff0c;小數部分將被舍去。 示例 1: 輸入: 4 輸出: 2 代碼 class Solution {public int mySqrt(int x) {int l0,rx;while (…

一個swiper 兩個分頁器的寫法【總結】

寫項目的時候&#xff0c;使用的是swiper插件呈現的效果是一個swiper要實現兩個分頁器&#xff0c;下面就來總結一下 以swiper3為例來寫&#xff0c;在頁面中引入jquery、swiper.min.js和swiper.min.css文件。 HTML結構&#xff1a; <div class"banner swiper-containe…

react路由守衛+重定向_React + Apollo:如何在重新查詢后進行重定向

react路由守衛重定向by Jun Hyuk Kim金俊赫 React Apollo&#xff1a;如何在重新查詢后進行重定向 (React Apollo: How to Redirect after Refetching a Query) GraphQL is hot, and for a good reason. In short, it is a query language that allows you to ask for exact…

python 爬蟲可視化編程_Python爬蟲爬取博客實現可視化過程解析

源碼&#xff1a;from pyecharts import Barimport reimport requestsnum0b[]for i in range(1,11):linkhttps://www.cnblogs.com/echoDetected/default.html?pagestr(i)headers{user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko…

tp6常用命令

TP6常用命令 1.創建控制器 php think make:controller --plain index** (php think make:controller --plain 控制器名稱&#xff08;首字母大寫&#xff09;)2.創建模型 php think make:model 【模塊名】/模型名 模型名為表名相當3.創建中間件 php think make:middleware 中…

Problem B: 字符類的封裝

Description 先來個簡單習題&#xff0c;練練手吧&#xff01;現在需要你來編寫一個Character類&#xff0c;將char這一基本數據類型進行封裝。該類中需要有如下成員函數&#xff1a; 1. 無參構造函數。 2. 構造函數Character(char)&#xff1a;用參數初始化數據成員。 3. void…

leetcode852. 山脈數組的峰頂索引(二分法)

我們把符合下列屬性的數組 A 稱作山脈&#xff1a; A.length > 3 存在 0 < i < A.length - 1 使得A[0] < A[1] < … A[i-1] < A[i] > A[i1] > … > A[A.length - 1] 給定一個確定為山脈的數組&#xff0c;返回任何滿足 A[0] < A[1] < … A[i…

linux 一鍵安裝lnmp

運行下面這天命令&#xff0c;回車 wget http://soft.vpser.net/lnmp/lnmp1.5.tar.gz -cO lnmp1.5.tar.gz && tar zxf lnmp1.5.tar.gz && cd lnmp1.5 && ./install.sh lnmp 選擇數據庫版本&#xff0c;回車 設置MySQL的root密碼&#xff08;為了安全不…

圖標下載

個人認為非常好的一個網站&#xff1a; http://www.easyicon.net/

以太坊ipfs_動手:Infura和以太坊上的IPFS入門

以太坊ipfsby Niharika Singh由Niharika Singh 動手&#xff1a;Infura和以太坊上的IPFS入門 (Hands On: Get Started With Infura and the IPFS on Ethereum) 為什么選擇Infura&#xff1f; (Why Infura?) There are a lot of pain points being faced by blockchain which …

suse required-start: mysql_suse linux 安裝MySql步驟

今天下午終于把mysql搞定了&#xff0c;我安裝的這個linux版本(suselinux10.0)自己帶的有Mysql&#xff0c;但是&#xff0c;在網上查的版本要比這高&#xff0c;所以就上網找了一個然后自己裝&#xff0c;但是從來沒有接觸過MySql也不知道該怎么裝&#xff0c;于是就上網找&am…

PHP上傳文件到七牛云和阿里云

七牛云上傳 注冊七牛云賬號并認證 進入控制臺找到對象存儲添加一個新的倉庫 添加完成之后看文檔 安裝 使用 Composer 安裝 Composer是 PHP 依賴管理工具。你可以在自己的項目中聲明所依賴的外部工具庫&#xff0c;Composer 會自動幫你安裝這些依賴的庫文件。 ???1. 安裝…

變態青蛙跳

2019獨角獸企業重金招聘Python工程師標準>>> 題目描述 一只青蛙一次可以跳上1級臺階&#xff0c;也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。 相比普通青蛙跳&#xff0c;這個 n級的就有點難了&#xff0c;重點是 能跳n級&…