ディープ春は詳細に元記事を--spring実際の使用を説明します

まず第一に、この記事では、私たちの春の注釈とコンフィギュレーションの基になって、遊びに行く、あなたは注釈と構成を使用していないことを確実にするための基盤を過小評価していないと言う、さらに基本となるソースコードを詳述しません。

私たちは、最初のコードのアドレスをダウンロードして行くことができる記事があります下に取得するために愛していない、Mavenプロジェクト、春のファイルの導入を確立します。自分がしようとする自分自身のダウンロードコードの後ろに、見て。それを見しようとしたときには、それを与えます。

1.基本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="car" class="com.springIOC.bean.CarBean"></bean>
</beans>
package com.springIOC;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext cac = new ClassPathXmlApplicationContext("config.xml");
        Object car = cac.getBean("car");
    }
}

それは私たちの漸進的なアプローチに少し、超簡単ではありません。

構成2.アノテーションベースのアプローチ

package com.springIOC2.config;

import com.springIOC.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean
        public CarBean car(){
        
        return new CarBean();
    }
}
package com.springIOC2;

import com.springIOC2.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        Object car = aca.getBean("car");
    }
}

私たちは、直接メソッド名を通じて私たちのオブジェクトを取得することができ、デフォルトの方法は、アセンブリに従ったものです。アセンブリの名前を指定する(値=「newnameの」)も@Beanことができます。

私たちは2019面接日時の情報を収集したように、それは、9月と10月は四半期を終了している文献がある、レイダースがあり、ビデオがあります。貧しい学生は、最新のインタビューレイダースの情報を受け取るために、公共号よりインタビューを送信する、[] Javaの親友することができます!サイファー[1024]他に送ったりしないでください.....

3. @ComponentScan用いてスキャン方法(フォーカス)のパッケージアセンブリ(basePackages = {「バッグフルパス」})

package com.springIOC3.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {"com.springIOC3"})
public class MainConfig {
}
package com.springIOC3;

import com.springIOC3.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = aca.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}

ここではいくつかのパラメータに関して、excludeFiltersは、構文は次のとおりである、オブジェクトの数を除外します

excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),  
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {RepositoryBean.class}) 
}

ANNOTATIONの5種類(クラスノート)、ASSIGNABLE_TYPE(クラス名)があるのfilterType、AspectJのは、(一般的に使用されていない、文書が言ったAspectJのタイプのパターン式のマッチング)、共通REGEX(正規表現のマッチング)、CUSTOM(カスタム)、私は赤の3種類をマーク。のは、特定の文言を見てみましょう

package com.springIOC3b.config;

import com.springIOC3b.repository.RepositoryBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

@Configuration
@ComponentScan(basePackages = {"com.springIOC3b"},excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {RepositoryBean.class})
}
)

public class MainConfig {
}

ちょうど今、私たちは、カスタムフィルタを話した、私たちはのtypeFilterインターフェースが真のリターンを持つ唯一の懸念、私たちの試合を書き換えることができます達成するために、自己定義されたフィルタを作成する方法を見てみましょう。こちらの場合は、

package com.springIOC3c.config;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;

public class CustomFilterType implements TypeFilter {
    @Override
        public Boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        
        Resource resource = metadataReader.getResource();
        if (classMetadata.getClassName().contains("RepositoryBean")) {
            
            return true;
        }
        
        
        
        return false;
    }
}

プロパティをfalse(全体のスキャンの真の表現)に設定されているuseDefaultFiltersへの必要性に注意を払う必要があり、私たちのincludeFiltersあるものの導入を可能にのみ含まれている逆もあります。まったく同じ構文とexcludeFilters

package com.springIOC3d.config;

import com.springIOC3d.service.ServiceBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

@Configuration
@ComponentScan(basePackages = {"com.springIOC3d"},includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = ServiceBean.class)
}
,useDefaultFilters = false)

public class MainConfig {
}

4.振り返ってみると、私たちは豆スコープを見てください。

@Lazy遅延読み込み、コードを見て、唯一のインスタンス化を使用して、我々はコンストラクタ豆、インスタンス化するときより容易に得るに参加。

package com.springIOC4.config;

import com.springIOC4.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
public class MainConfig {
    @Bean
        @Lazy
        public CarBean car(){
        return new CarBean();
    }
}

@Scpoeを指定することができる4つのスコープがあります。

A)シングルトン非遅延ロード・インスタンス化オブジェクトが生成された後に単一のインスタンス(デフォルト)は、容器の単一の実施形態のライフサイクルは、スプリングばねを有するように、コンテナオブジェクトの破壊は、破壊されます

package com.springIOC4b.config;

import com.springIOC4b.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

@Configuration
public class MainConfig {
    @Bean
        @Scope(value = "singleton")
        public CarBean car(){
        return new CarBean();
    }
}
package com.springIOC4b;

import com.springIOC4b.bean.CarBean;
import com.springIOC4b.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        CarBean car = (CarBean)aca.getBean("car");
        CarBean car2 = (CarBean)aca.getBean("car");
        System.out.println(car == car2);
        
    }
}

出力は、我々はシングルトンオブジェクト、オブジェクトのシングルトン、スプリングによって管理ライフサイクルであることを、事実です。

B)プロトタイプマルチインスタンス

package com.springIOC4c.config;

import com.springIOC4c.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class MainConfig {
    @Bean
        @Scope(value = "prototype")
        public CarBean car(){
        return new CarBean();
    }
}
package com.springIOC4c;

import com.springIOC4c.bean.CarBean;
import com.springIOC4c.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        CarBean car = (CarBean)aca.getBean("car");
        CarBean car2 = (CarBean)aca.getBean("car");
        System.out.println(car == car2);
        
    }
}

クリーンアップ、並びに要求及びセッションレベルとのセッションで要求にGCによって破壊されたときに、IOCコンテナ複数のケースを管理しないように、ここで実証されていません。

ビーンの注入かどうかを判断するための設定注釈@ 5.。

package com.springIOC5.config;

import com.springIOC5.bean.CarBean;
import com.springIOC5.bean.UserBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean(value = "user")
        public UserBean userBean() {
        return new UserBean();
    }
    @Bean
        @Conditional(value = IOCConditional.class)
        public CarBean carBean() {
        return new CarBean();
    }
}
package com.springIOC5.config;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class IOCConditional implements Condition {
    @Override
        public Boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        if (context.getBeanFactory().containsBean("user")) {
            
            return true;
        }
        return false;
    }
}

上記のコードは、それが何を意味するのでしょうか?それは私たちがcarBeanを注入する必要があるかどうか、である、このオブジェクトは、ユーザーが含まれている場合、あなたが私たちのcarBeanを注入、注入が含まれていない、物事の意味があり、コンフィギュレーション設定は、クラス内に注入オーダーである、我々は、審査員として、私たちの条件を置く必要があります上部の豆は、そうでなければ、それは条件付きビーン判断基準を認識する必要はありません。

6.インポートが導入@やり方注入ビーン

package com.springIOC6.config;

import com.springIOC6.bean.CarBean;
import com.springIOC6.bean.UserBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({
    CarBean.class, UserBean.class
}
)
public class MainConfig {
}

我々はまた、のは、それを変更させ、達成するためのインターフェースを使用することができ、注入することができるクラスで直接メモを書きます。

package com.springIOC6b.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({
    ImportSelector.class
}
)
public class MainConfig {
}
package com.springIOC6b.config;

import org.springframework.core.type.AnnotationMetadata;

public class ImportSelector implements org.springframework.context.annotation.ImportSelector {
    @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{
            "com.springIOC6b.bean.CarBean","com.springIOC6b.bean.UserBean"
        }
        ;
    }
}

ImportSelectorクラスを達成し、クラス名への完全なパスを返します。自動アセンブリは@import実装をベースにしています。

registerBeanDefinitionsメソッドを書き換え、ImportBeanDefinitionRegistrarを実現する、ことも可能です。

package com.springIOC6c.config;

import com.springIOC6c.bean.CarBean;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class ImportSelectorRegister implements ImportBeanDefinitionRegistrar {
    @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(CarBean.class);
        registry.registerBeanDefinition("CarBean",rootBeanDefinition);
    }
}

FactoryBeanのを注入することにより7.

package com.springIOC7.config;

import com.springIOC7.bean.UserBean;
import org.springframework.beans.factory.FactoryBean;

public class IOCFactoryBean implements FactoryBean<UserBean> {
    @Override
        public UserBean getObject() throws Exception {
        
        return new UserBean();
    }
    @Override
        public Class<?> getObjectType() {
        
        return UserBean.class;
    }
    @Override
        public Boolean isSingleton() {
        
        return true;
    }
}
package com.springIOC7.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean
        public IOCFactoryBean iocFactoryBean(){
        return new IOCFactoryBean();
    }
}
package com.springIOC7;

import com.springIOC7.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        Object carBean = aca.getBean("iocFactoryBean");
        
        System.out.println(carBean);
        Object iocFactoryBean = aca.getBean("&iocFactoryBean");
        
        System.out.println(iocFactoryBean);
    }
}

それはすべて、これはすべての方法仕上がりにIOCのコンテナにコンポーネントを追加することになると、簡単に要約:

  • @Bean注射は、スコープの4種類の単一の実施形態、(IOC容器ライフサイクル管理ではない)多くの場合、セッションの要求を指定することができる、遅延読み込みを提供することができます、
  • @・コントローラーで、リポジトリ@、サービス@、使用するコンポーネントの注釈@、パケットインジェクションをスキャンする方法を指定@ComponentScan。
  • @import注入モード、および2つの実装クラスImportSelector ImportBeanDefinitionRegistrar二つの方法。
  • @FactoryBean、エンジニアリング豆のやり方も注入することができます。注意することなく行われる&究極のオブジェクトは、実際のバンド&豆を得ることです。3つの方法は、指定されたオブジェクト、指定されたタイプは、単一の実施形態かどうかを指定します。

単一のBeanインスタンスの場合は、その後、コンテナの起動時に、Beanオブジェクトが作成され、コンテナはまた、Beanの破壊メソッドを呼び出されたときに破壊されました。

Beanが作成されず、IOC容器から破壊の豆、豆および管理を取得する際に作成されたとき、マルチインスタンス豆、次いで容器を開始。

1.破壊の私達の初期化メソッドとメソッドを指定するにinitMethodとdestroyMethodをして、のが最も簡単な方法を見てみましょう

package com.springlifeCycle1a.config;

import com.springlifeCycle1a.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destroy")
        public CarBean car() {
        return new CarBean();
    }
}

私たちは、私たちの最初のinitメソッドを指定する方法を破壊する方法を破壊します。、カーコンストラクタ、車のinitメソッドで注文するために呼び出す、destroyメソッドの車は、あなたも@Lazy独自のアノテーションを使用して試すことができます。コードコード、あなたが試すことができます行く雲があります。

2. InitializingBeanとDisposableBean 2つのインタフェース豆の初期化および破壊方法

package com.springlifeCycle2a.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class CarBean implements InitializingBean, DisposableBean {
    public CarBean() {
        System.out.println("我是Car");
    }
    public void afterPropertiesSet() {
        System.out.println("我是初始化init");
    }
    public void destroy() {
        System.out.println("我是销毁destroy");
    }
}

の方法により提供されたアノテーションと@PostConstruct @ProDestory 3 JSR250標準ノート

package com.springlifeCycle3.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class CarBean {
    public CarBean() {
        System.out.println("我是Car");
    }
    @PostConstruct
    public void init() {
        System.out.println("我是初始化init--PostConstruct");
    }
    @PreDestroy
    public void destory() {
        System.out.println("我是销毁destroy--PreDestroy");
    }    
}

すべてのBeanの作成をインターセプトしBeanPostProcessorの春4.ポ​​ストプロセッサ豆(時間を話すこの方法の背後にあるソースは内部で、話のソースコードを見て必要性を感じるように実装されます)

package com.springlifeCycle4.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class LifeBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化方法" + beanName);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("销毁方法" + beanName);
        return bean;
    }
}

、4の合計を指定するための我々の方法の破壊のコンテナオブジェクトとメソッド内の初期化メソッドを総括もあります

  • initMethodとdestroyMethodをの@Beanと初期の方法として与えられたと方法を破壊します。
  • 実装Beanの初期化と破壊InitializingBeanによる方法およびDisposableBean二つのインターフェース。
  • ラベル@ProDestory JSR250仕様によって提供@PostConstructアノテーションおよび方法。
  • BeanPostProcessorの春によるポストプロセッサBeanは、すべてのBeanの作成プロセスをインターセプトします。

ここでは多くの何かが、私はできるだけ早く問題について言うのです、私たちは見て3つの方法の割り当て。

package com.springValue.config;

import com.springValue.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = "classpath:carBean.properties",encoding = "utf-8") //指定外部文件的位置
public class MainConfig {
    @Bean
    public CarBean carBean() {
        return new CarBean();
    }
}
import org.springframework.beans.factory.annotation.Value;

public class CarBean {
    @Value("宝马")
    private String name;
    @Value("#{5-2}")
    private int carNum;
    @Value("${carBean.realName}")
    private String realName;        
}

=「UTF-8」、それ以外の文字が文字化けしますインポートファイルのエンコードについての最もよいセットで言及する価値があります。

アクティブなアセンブリは、のレビューをさせ、また最大であると、通常は最もよく知られています。

IOCコンテナアセンブリに見られる同じタイプの複数が、その後、属性名に従って組み立てられる場合に第1のアセンブリは、の種類に応じて組み付けられる自動Autowired @ 1

package com.springxAutowired1.config;

import com.springxAutowired1.dao.AutowiredDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value = "com.springxAutowired1.service")
public class MainConfig {
    @Bean
    public AutowiredDao autowiredDao1(){
        return new AutowiredDao(1);
    }
    @Bean
    public AutowiredDao autowiredDao2(){
        return new AutowiredDao(2);
    }
}
package com.springxAutowired1.service;

import com.springxAutowired1.dao.AutowiredDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ServiceBean {
    @Autowired
    private AutowiredDao autowiredDao2;
    public ServiceBean() {
        System.out.println("我是serviceBean");
    }
    @Override
    public String toString() {
        return "ServiceBean{" +
                "AutowiredDao=" + autowiredDao2 +
                '}';
    }
}

ここでは1として識別される2つのAutowiredDao、アセンブリへの名前でラベルされた2、ServiceBeanデフォルトの目標を設定しました。

2.我々はまた、@Qualifierにより、アセンブリの名前を指定することができます。

package com.springxAutowired1b.service;

import com.springxAutowired1b.dao.AutowiredDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class ServiceBean {
    @Autowired
    @Qualifier(value = "autowiredDao1")
    private AutowiredDao autowiredDao2;
    public ServiceBean() {
        System.out.println("我是serviceBean");
    }
    @Override
    public String toString() {
        return "ServiceBean{" +
                "AutowiredDao=" + autowiredDao2 +
                '}';
    }
}

3.私たちは、その後、我々は異常なスローを防ぐために= falseを必要と使用することができますが、名前が間違っている場合は、間違ったアセンブリは、エラーの可能性があります修飾子を使用します

package com.springxAutowired3.service;

import com.springxAutowired3.dao.AutowiredDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class ServiceBean {
    @Qualifier(value = "autowiredDaoError")
    @Autowired(required = false)
    private AutowiredDao autowiredDao2;
    public ServiceBean() {
        System.out.println("我是serviceBean");
    }
    @Override
    public String toString() {
        return "ServiceBean{" +
                "AutowiredDao=" + autowiredDao2 +
                '}';
    }
}

注:私はここに@Resource注釈を言わなかった、この注釈は実際にはしないばねであり、JSR250の標準ですが、サポート@Primaryと@Qualifierをサポートしていません。

時々、私たちはさまざまな環境を通じて、当社の設定を切り替える必要があり、我々は、@Profileは環境によって異なる豆を識別アクティブにするノート渡さ

クラスのロゴ@Profile、現在の環境にマッチするだけで、クラス全体の構成が有効になります

豆、豆の@Profileロゴのみ現在の環境がアクティブになります

package com.springxAutowired4.config;

import com.springxAutowired4.bean.Environment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
public class MainConfig {
    @Bean
    @Profile(value = "test")
    public Environment environment_test() {
        return new Environment("test");
    }
    @Bean
    @Profile(value = "dev")
    public Environment environment_dev() {
        return new Environment("dev");
    }
    @Bean
    @Profile(value = "pro")
    public Environment environment_pro() {
        return new Environment("pro");
    }
}

スイッチング環境を活性化する方法

  • 方法:英語中間カンマ区切りのJVMランタイムパラメータ、パラメータテーブルのPRODの複数-Dspring.profiles.active =テスト、DEVを切り替えます
  • 方法IIは:コードの方法によって活性化されます
package com.springxAutowired4;

import com.springxAutowired4.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    /**
     * 环境切换
     * @param args
     */
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext();
        aca.getEnvironment().setActiveProfiles("test","dev");//方便演示,我写了两个,一般都是一个的.
        aca.register(MainConfig.class);
        aca.refresh();
        for (String beanDefinitionName : aca.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }
}

両方が書かれている場合は、コードはパラメータもはや作品に基づいて実装されています


「短いステップ、千マイルは、」あなたができる将来の希望は:どこでも夢の馬の生息地を持っています!、ジュニアさあ!

いいえ公共の懸念:「ジャワの親友」、更新毎日のJavaの知識はああ、あなたの到着を楽しみにしていません!

  • 「送信グループを 10万人のプログラマーとの進展を」。
  • 「送信インタビューを情報BATJのインタビュー、ビデオインタビューレイダースを受け取るために」。
  • 「送信楽しいアルゴリズムをビデオチュートリアルの「楽しいアルゴリズム」シリーズを受け取るために」。
  • 「送信しない1024」...

おすすめ

転載: www.cnblogs.com/java-friend/p/11582999.html
おすすめ