主頁 >  其他 > Java程式員必備框架—Spring全家桶的前世今生詳細梳理

Java程式員必備框架—Spring全家桶的前世今生詳細梳理

2021-08-01 06:44:07 其他

前言

在作業中經常會發現很多同事連最常用的SSM框架使用起來也經常忘這忘那的,關于spring甚至只記得IOC、DI、AOP,然后就在網上找資料浪費大部分時間,所以本文重溫了一遍幫大伙加深理解,同時做個整理,以后再忘來看這篇文章就好了,

我平時也會收集一些不錯的spring學習書籍PDF,畢竟程式員的書都挺貴的,不可能每本都買物體,自己啃完也會梳理學習筆記,都在這了>>spring一網打盡,直接點擊就可以無償獲取,

1. 體系結構

image

Spring是模塊化的,可以選擇合適的模塊來使用,其體系結構分為5個部分,分別為:

Core Container

核心容器:Spring最主要的模塊,主要提供了IOC、DI、BeanFactory、Context等,列出的這些學習過Spring的同學應該都認識

Data Access/Integration

資料訪問/集成:即有JDBC的抽象層、ORM物件關系映射API、還有事務支持(重要)等

Web

Web:基礎的Web功能如Servlet、http、Web-MVC、Web-Socket等

Test

測驗:支持具有Junit或TestNG框架的Spring組件測驗

其他

AOP、Aspects(面向切面編程框架)等

2. IOC

2.1 引入耦合概念

耦合:即是類間或方法間的依賴關系,編譯時期的依賴會導致后期維護十分困難,一處的改動導致其他依賴的地方都需改動,所以要解耦

解耦:解除程式間的依賴關系,但在實際開發中我們只能做到編譯時期不依賴,運行時期才依賴即可,沒有依賴關系即沒有必要存在了

解決思路:使用Java的反射機制來避免new關鍵字(通過讀取組態檔來獲取物件全限定類名)、使用工廠模式

2.2 IOC容器

Spring框架的核心,主要用來存放Bean物件,其中有個底層BeanFactory介面只提供最簡單的容器功能(特點延遲加載),一般不使用,常用的是其子類介面ApplicationContext介面(創建容器時立即實體化物件,繼承BeanFactory介面),提供了高級功能(訪問資源,決議檔案資訊,載入多個繼承關系的背景關系,攔截器等),

ApplicationContext介面有三個實作類:ClassPathXmlApplicationContext、FileSystemoXmlApplication、AnnotionalConfigApplication,從名字可以知道他們的區別,下面講解都將圍繞ApplicationContext介面,

容器為Map結構,鍵為id,值為Object物件,

2.2.1 Bean的創建方式

無參構造

只配了id、class標簽屬性(此時一定要有無參函式,添加有參構造時記得補回無參構造)

普通工廠創建

可能是別人寫好的類或者jar包,我們無法修改其原始碼(只有位元組碼)來提供無參建構式,eg:

// 這是別人的jar包是使用工廠來獲取實體物件的
public class InstanceFactory {
    public User getUser() {
        return new User();
    }
}

 <!--  工廠類  -->
<bean id="UserFactory" class="com.howl.entity.UserFactory"></bean>
<!--  指定工廠類及其生產實體物件的方法  -->
<bean id="User" factory-bean="UserFactory" factory-method="getUser"></bean>

靜態工廠創建

<!--  class使用靜態工廠類,方法為靜態方法生產實體物件  -->
<bean id="User" class="com.howl.entity.UserFactory" factory-method="getUser"></bean>

2.2.2 Bean標簽

該標簽在applicationContext.xml中表示一個被管理的Bean物件,Spring讀取xml組態檔后把內容放入Spring的Bean定義注冊表,然后根據該注冊表來實體化Bean物件將其放入Bean快取池中,應用程式使用物件時從快取池中獲取

屬性描述
class指定用來創建bean類
id唯一的識別符號,可用 ID 或 name 屬性來指定 bean 識別符號
scope物件的作用域,singleton(默認)/prototype
lazy-init是否懶創建 true/false
init-method初始化呼叫的方法
destroy-methodx銷毀呼叫的方法
autowire不建議使用,自動裝配byType、byName、constructor
factory-bean指定工廠類
factory-method指定工廠方法
元素描述
constructor-arg建構式注入
properties屬性注入
元素的屬性描述
type按照型別注入
index按照下標注入
name按照名字注入,最常用
value給基本型別和String注入
ref給其他bean型別注入
元素的標簽描述
<list>
<Set>
<Map>
<props>

2.2.3 使用

注意:默認使用無參建構式的,若自己寫了有參構造,記得補回無參構造

XML

<bean id="User" class="com.howl.entity.User"></bean>

ApplicationContext ac = new ClassPathXmlApplicationContext
("applicationContext.xml");
User user = (User) ac.getBean("User");
user.getName();

注解

前提在xml組態檔中開啟bean掃描

<context:component-scan base-package="com.howl.entity"></context:component-scan>

// 默認是類名首字母小寫
@Component(value="User")
public class User{
    int id;
    String name;
    String eamil;
}

2.2.4 生命周期

單例:與容器同生共死

多例: 使用時創建,GC回收時死亡

3. DI

Spring框架的核心功能之一就是通過依賴注入的方式來管理Bean之間的依賴關系,能注入的資料型別有三類:基本型別和String,其他Bean型別,集合型別,注入方式有:建構式,set方法,注解

3.1 基于建構式的注入

<!--  把物件的創建交給Spring管理  -->
<bean id="User" class="com.howl.entity.User">
    <constructor-arg type="int" value="1"></constructor-arg>
    <constructor-arg index="1" value="Howl"></constructor-arg>
    <constructor-arg name="email" value="xxx@qq.com"></constructor-arg>
    <constructor-arg name="birthday" ref="brithday"></constructor-arg>
</bean>

<bean id="brithday" class="java.util.Date"></bean>

3.2 基于setter注入(常用)

被注入的bean一定要有setter函式才可注入,而且其不關心屬性叫什么名字,只關心setter叫什么名字

<bean id="User" class="com.howl.entity.User">
    <property name="id" value="1"></property>
    <property name="name" value="Howl"></property>
    <property name="email" value="XXX@qq.com"></property>
    <property name="birthday" ref="brithday"></property>
</bean>

<bean id="brithday" class="java.util.Date"></bean>

3.3 注入集合

內部有復雜標簽、、、這里使用setter注入

<bean id="User" class="com.howl.entity.User">

	<property name="addressList">
		<list>
			<value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <ref bean="address2"/>
        </list>
    </property>

    <property name="addressSet">
        <set>
            <value>INDIA</value>
            <ref bean="address2"/>
            <value>USA</value>
            <value>USA</value>
        </set>
    </property>

    <property name="addressMap">
        <map>
            <entry key="1" value="INDIA"/>
            <entry key="2" value-ref="address1"/>
            <entry key="3" value="USA"/>
        </map>
    </property>

    <property name="addressProp">
        <props>
            <prop key="one">INDIA</prop>
            <prop key="two">Pakistan</prop>
            <prop key="three">USA</prop>
            <prop key="four">USA</prop>
        </props>
    </property>

</bean>

3.4 注解

@Autowired:自動按照型別注入(所以使用注解時setter方法不是必須的,可用在變數上,也可在方法上),若容器中有唯一的一個bean物件型別和要注入的變數型別匹配就可以注入;若一個型別匹配都沒有,則報錯;若有多個型別匹配時:先匹配全部的型別,再繼續匹配id是否有一致的,有則注入,沒有則報錯

@Qualifier:在按照型別注入基礎上按id注入,給類成員變數注入時不能單獨使用,給方法引數注入時可以單獨使用

@Resource:上面二者的結合

注意:以上三個注入只能注入bean型別資料,不能注入基本型別和String,集合型別的注入只能通過XMl方式實作

@Value:注入基本型別和String資料

承接上面有個User類了

@Component(value = "oneUser")
@Scope(value = "singleton")
public class OneUser {

    @Autowired	// 按型別注入
    User user;

    @Value(value = "注入的String型別")
    String str;

    public void UserToString() {
        System.out.println(user + str);
    }
}

3.5 配置類(在SpringBoot中經常會遇到)

配置類等同于aplicationContext.xml,一般配置類要配置的是需要引數注入的bean物件,不需要引數配置的直接在類上加@Component

/**
 * 該類是個配置類,作用與applicationContext.xml相等
 * @Configuration表示配置類
 * @ComponentScan(value = {""})內容可以傳多個,表示陣列
 * @Bean 表示將回傳值放入容器,默認方法名為id
 * @Import 匯入其他配置類
 * @EnableAspectJAutoProxy 表示開啟注解
 */
@Configuration
@Import(OtherConfiguration.class)
@EnableAspectJAutoProxy
@ComponentScan(value = {"com.howl.entity"})
public class SpringConfiguration {

    @Bean(value = "userFactory")
    @Scope(value = "prototype")
    public UserFactory createUserFactory(){

        // 這里的物件容器管理不到,即不能用@Autowired,要自己new出來
        User user = new User();

        // 這里是基于建構式注入
        return new UserFactory(user);
    }
}

@Configuration
public class OtherConfiguration {

    @Bean("user")
    public User createUser(){
        User user = new User();

        // 這里是基于setter注入
        user.setId(1);
        user.setName("Howl");
        return user;
    }
}

4. AOP

4.1 動態代理

動態代理:基于介面(invoke)和基于子類(Enhancer的create方法),基于子類的需要第三方包cglib,這里只說明基于介面的動態代理,筆者 動態代理的博文

Object ob = Proxy.newProxyInstance(mydog.getClass().getClassLoader(), mydog.getClass().getInterfaces(),new InvocationHandler(){

    // 引數依次為:被代理類一般不使用、使用的方法、引數的陣列
    // 回傳值為創建的代理物件
    // 該方法會攔截類的所有方法,并在每個方法內注入invoke內容
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 只增強eat方法
            if(method.getName().equals("eat")){
                System.out.println("吃肉前洗手");
                method.invoke(mydog, args);
            }else{
                method.invoke(mydog, args);
            }
            return proxy;
        }
})

4.2 AOP

相關術語:

連接點:這里指被攔截的方法(Spring只支持方法)

通知:攔截到連接點要執行的任務

切入點:攔截中要被增強的方法

織入:增強方法的程序

代理物件:增強功能后回傳的物件

切面:整體的結合,什么時候,如何增強方法

xml配置

<!-- 需要額外的jar包,aspectjweaver運算式需要 -->

<!--  被切入的方法  -->
<bean id="accountServiceImpl" class="com.howl.interfaces.impl.AccountServiceImpl"></bean>

<!--  通知bean也交給容器管理  -->
<bean id="logger" class="com.howl.util.Logger"></bean>

<!--  配置aop  -->
<aop:config>

    <aop:pointcut id="pt1" expression="execution(* com.howl.interfaces..*(..))"/>

    <aop:aspect id="logAdvice" ref="logger">
        <aop:before method="beforeLog" pointcut-ref="pt1"></aop:before>
        <aop:after-returning method="afterReturningLog" pointcut-ref="pt1"></aop:after-returning>
        <aop:after-throwing method="afterThrowingLog" pointcut-ref="pt1"></aop:after-throwing>
        <aop:after method="afterLog" pointcut="execution(* com.howl.interfaces..*(..))"></aop:after>

        <!--  配置環繞通知,測驗時請把上面四個注釋掉,排除干擾  -->
        <aop:around method="aroundLog" pointcut-ref="pt1"></aop:around>

    </aop:aspect>
</aop:config>

<!-- 切入運算式 -->
<!-- 訪問修飾符 . 回傳值 . 包名 . 包名 . 包名,,, . 類名 . 方法名(引數串列) -->
<!-- public void com.howl.Service.UserService.deleteUser() -->
<!-- 訪問修飾符可以省略 -->
<!-- * 表示通配,可用于修飾符,回傳值,包名,方法名 -->
<!-- .. 標志當前包及其子包 -->
<!-- ..可以表示有無引數,*表示有引數 -->
<!-- * com.howl.service.*(..) -->

<!-- 環繞通知是手動編碼方式實作增強方法合適執行的方式,類似于invoke? -->

即環繞通知是手動配置切入方法的,且Spring框架提供了ProceedingJoinPoint,該介面有一個proceed()和getArgs()方法,此方法就明確相當于呼叫切入點方法和獲取引數,在程式執行時,spring框架會為我們提供該介面的實作類供我們使用

// 抽取了公共的代碼(日志)
public class Logger {

    public void beforeLog(){
        System.out.println("前置通知");
    }

    public void afterReturningLog(){
        System.out.println("后置通知");
    }

    public void afterThrowingLog(){
        System.out.println("例外通知");
    }

    public void afterLog(){
        System.out.println("最終通知");
    }

    // 這里就是環繞通知
    public Object aroundLog(ProceedingJoinPoint pjp){

        Object rtValue = null;

        try {

            // 獲取方法引數
            Object[] args = pjp.getArgs();

            System.out.println("前置通知");

            // 呼叫業務層方法
            rtValue = pjp.proceed();

            System.out.println("后置通知");

        } catch (Throwable t) {
            System.out.println("例外通知");
            t.printStackTrace();
        } finally {
            System.out.println("最終通知");
        }
        return rtValue;
    }

}

基于注解的AOP

<!-- 配置Spring創建容器時要掃描的包,主要掃描被切入的類,以及切面類 -->
<context:compinent-scan base-package="com.howl.*"></context:compinent-scan>

<!-- 這二者的類上要注解 @Compinent / @Service -->

<!-- 開啟AOP注解支持 -->
<aop:aspectj:autoproxy></aop:aspectj:autoproxy>>

注意要在切面類上加上注解表示是個切面類,四個通知在注解中通知順序是不能決定的且亂序,不建議使用,不過可用環繞通知代替 ,即注解中建議使用環繞通知來代替其他四個通知

// 抽取了公共的日志
@Component(value = "logger")
@Aspect
public class Logger {

    @Pointcut("execution(* com.howl.interfaces..*(..))")
    private void pt1(){}

    @Before("pt1()")
    public void beforeLog(){
        System.out.println("前置通知");
    }

    @AfterReturning("pt1()")
    public void afterReturningLog(){
        System.out.println("后置通知");
    }

    @AfterThrowing("pt1()")
    public void afterThrowingLog(){
        System.out.println("例外通知");
    }

    @After("pt1()")
    public void afterLog(){
        System.out.println("最終通知");
    }

    @Around("pt1()")
    public Object aroundLog(ProceedingJoinPoint pjp){

        Object rtValue = null;

        try {

            // 獲取方法引數
            Object[] args = pjp.getArgs();

            System.out.println("前置通知");

            // 呼叫業務層方法
            rtValue = pjp.proceed();

            System.out.println("后置通知");

        } catch (Throwable t) {
            System.out.println("例外通知");
            t.printStackTrace();
        } finally {
            System.out.println("最終通知");
        }
        return rtValue;
    }

}

5. 事務

Spring提供了宣告式事務和編程式事務,后者難于使用而選擇放棄,Spring提供的事務在業務層,是基于AOP的

5.1 宣告式事務

從業務代碼中分離事務管理,僅僅使用注釋或 XML 配置來管理事務,Spring 把事務抽象成介面 org.springframework.transaction.PlatformTransactionManager ,其內容如下,重要的是其只是個介面,真正實作類是:org.springframework.jdbc.datasource.DataSourceTransactionManager

public interface PlatformTransactionManager {
    // 根據定義創建或獲取當前事務
   TransactionStatus getTransaction(TransactionDefinition definition);
   void commit(TransactionStatus status);
   void rollback(TransactionStatus status);
}

TransactionDefinition事務定義資訊

public interface TransactionDefinition {
   int getPropagationBehavior();
   int getIsolationLevel();
   String getName();
   int getTimeout();
   boolean isReadOnly();
}

因為不熟悉所以把程序全部貼下來

5.2 xml配置

建表

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `money` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

entity

public class Account {

    private int id;
    private int money;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public Account(int id, int money) {
        this.id = id;
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", money=" + money +
                '}';
    }
}

Dao層

public interface AccountDao {

    // 查找賬戶
    public Account selectAccountById(int id);

    // 更新賬戶
    public void updateAccountById(@Param(value = "id") int id, @Param(value = "money") int money);

}

Mapper層

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.howl.dao.AccountDao">

    <select id="selectAccountById" resultType="com.howl.entity.Account">
        SELECT * FROM account WHERE id = #{id};
    </select>

    <update id="updateAccountById">
        UPDATE account SET money = #{money} WHERE id = #{id}
    </update>

</mapper>

Service層

public interface AccountService {

    public Account selectAccountById(int id);

    public void transfer(int fid,int sid,int money);

}

Service層Impl

public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    public Account selectAccountById(int id) {
        return accountDao.selectAccountById(id);
    }

    // 這里只考慮事務,不關心錢額是否充足
    public void transfer(int fid, int sid, int money) {

        Account sourceAccount = accountDao.selectAccountById(fid);
        Account targetAccount = accountDao.selectAccountById(sid);

        accountDao.updateAccountById(fid, sourceAccount.getMoney() - money);

        // 例外
         int i = 1 / 0;

        accountDao.updateAccountById(sid, targetAccount.getMoney() + money);
    }
}

applicationContext.xml配置

<!--  配置資料源,spring自帶的沒有連接池功能  -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/spring"></property>
    <property name="username" value="root"></property>
    <property name="password" value=""></property>
</bean>

<!--  配置sqlSessionFactory工廠  -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--  業務層bean  -->
<bean id="accountServiceImpl" class="com.howl.service.impl.AccountServiceImpl" lazy-init="true">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>

<!--  事務管理器  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--  配置事務通知,可以理解為Logger  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!--  配置事務的屬性
      isolation:隔離界別,默認使用資料庫的
      propagation:轉播行為,默認REQUIRED
      read-only:只有查詢方法才需要設定true
      timeout:默認-1永不超時
      no-rollback-for
      rollback-for

      -->
    <tx:attributes>
        <!--  name中是選擇匹配的方法  -->
        <tx:method name="select*" propagation="SUPPORTS" read-only="true"></tx:method>
        <tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
    </tx:attributes>
</tx:advice>

<!--  配置AOP  -->
<aop:config>
    <aop:pointcut id="pt1" expression="execution(* com.howl.service.impl.AccountServiceImpl.transfer(..))"/>
    <!--  建立切入點運算式與事務通知的對應關系  -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>

測驗

public class UI {

    public static void main(String[] args) {

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

        AccountService accountService = (AccountService) ac.getBean("accountServiceImpl");

        Account account = accountService.selectAccountById(1);
        System.out.println(account);

        accountService.transfer(1,2,100);
    }
}

正常或發生例外都完美運行

個人覺得重點在于配置事務管理器(而像資料源這樣是日常需要)

事務管理器:管理獲取的資料庫連接

事務通知:根據事務管理器來配置所需要的通知(類似于前后置通知)

上面兩個可以認為是合一起配一個通知,而下面的配置方法與通知的映射關系

AOP配置:用特有的<aop:advisor>標簽來說明這是一個事務,需要在哪些地方切入

5.3 注解事務

  1. 配置事務管理器(和xml一樣必須的)
  2. 開啟Spring事務注解支持<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
  3. 在需要注解的地方使用@Transaction
  4. 不需要AOP,是因為@Transaction注解放在了哪個類上就說明哪個類需要切入,里面所有方法都是切入點,映射關系已經存在了

在AccountServiceImpl中簡化成,xml中可以選擇方法匹配,注解不可,只能這樣配

@Service(value = "accountServiceImpl")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class AccountServiceImpl implements AccountService {

    // 這里為了獲取Dao層
    @Autowired
    private AccountDao accountDao;

    // 業務正式開始

    public Account selectAccountById(int id) {
        return accountDao.selectAccountById(id);
    }

    // 這里只考慮事務,不關心錢額是否充足
    @Transactional(propagation = Propagation.REQUIRED,readOnly = false)
    public void transfer(int fid, int sid, int money) {

        Account sourceAccount = accountDao.selectAccountById(fid);
        Account targetAccount = accountDao.selectAccountById(sid);

        accountDao.updateAccountById(fid, sourceAccount.getMoney() - money);

        // 例外
        // int i = 1 / 0;

        accountDao.updateAccountById(sid, targetAccount.getMoney() + money);
    }
}

6. Test

應用程式的入口是main方法,而JUnit單元測驗中,沒有main方法也能執行,因為其內部集成了一個main方法,該方法會自動判斷當前測驗類哪些方法有@Test注解,有就執行,

JUnit不會知道我們是否用了Spring框架,所以在執行測驗方法時,不會為我們讀取Spring的組態檔來創建核心容器,所以不能使用@Autowired來注入依賴,

解決方法:

  1. 匯入JUnit包
  2. 匯入Spring整合JUnit的包
  3. 替換Running,@RunWith(SpringJUnit4ClassRunner.class)
  4. 加入組態檔,@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
//@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UITest {

    @Autowired
    UserFactory userFactory;

    @Test
    public void User(){
        System.out.println(userFactory.getUser().toString());
    }
}

7. 注解總覽

@Component
@Controller
@Service
@Repository

@Autowired
@Qualifier
@Resource
@Value
@Scope

@Configuration
@ComponentScan
@Bean
@Import
@PropertySource()

@RunWith
@ContextConfiguration

@Transactional

8. 總結

學完Spring之后感覺有什么優勢呢?

  • IOC、DI:方便降耦

  • AOP:重復的功能形成組件,在需要處切入,切入出只需關心自身業務甚至不知道有組件切入,也可把切入的組件放到開發的最后才完成

  • 宣告式事務的支持

  • 最小侵入性:不用繼承或實作他們的類和介面,沒有系結了編程,Spring盡可能不讓自身API弄亂開發者代碼

  • 整合測驗

  • 方便集成其他框架


好了,本文就寫到這里吧,我的學習秘籍都在這了>>spring一網打盡,直接點擊就可以直接白嫖了!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291182.html

標籤:其他

上一篇:適合小白學的基礎知識—SSTI漏洞學習

下一篇:【程式人生】階段總結-翰墨流離

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more