EDITORIAL言葉
対象読者:それは私が言っているか理解していない可能性があるため、いくつかの経験を有するものは、これは、初心者向けではありません
記事の思考:ちょうど他のBeanのライフサイクル、などの記事、ソースコードの解釈(あなたがソースコードの束をスティック)のようなブログを開始しません。個人的に質問によって駆動されなければならないと感じ、なぜたBeanFactoryの出現がある、なぜそこにライフサイクルがあります。
テキスト
私たちが演奏しているように、我々は、VO、PO、エンティティ、DTOとして、簡単な豆を豆を使用して開始されています
XXEntity xxEntity = new XXEntity();
xxEntity.setPropA("字符串");
オブジェクトのプロパティとして、あなたが(ない真剣に、唯一の例)建設またはポスト建設の時に値を設定する必要があり、複雑な豆、背後にあるかもしれません
// 构建序列化实例,这里 Serializable 是接口,使用接口的好处是在使用别的序列化时,不需要修改 jedis 类
Serializable fastJsonSerizlizable = new FastJsonSerizlizable();
// 构建目标 jedis 实例 ,需要先构建序列化对象
Jedis jedis = new Jedis();
jedis.setSerializable(fastJsonSerizlizable);
そして、サービスA serviceBクラスと使用Redisのに必要性が、私は経験豊富な学生がjedisを作成するクラスのツールを書きます、各クラスで再びそれを書き込む処理のjedis例に行くことができないクラスは、来ましたこのような
public BeanUtil {
// 可以把创建序列化单拿出来,因为除了 redis 需要序列化之外,kafka 也需要序列化
public static Serializable createSerializable(){
return new FastJsonSerizlizable();
}
public static Jedis createJedis(){
Jedis jedis = new Jedis();
jedis.setSerializable(createSerializable());
return jedis;
}
}
// 这里我 serviceA,serviceB 都可以使用 createJedis 来直接获取 jedis 实例 ,而不需要关心创建细节,使用哪个序列化等问题
上記のコードではいくつかの問題があります
- Jedisは、オブジェクト、および直列化可能オブジェクトに対する個々の意志jedis件名を使用するたびに作成されますが、物事のfastJsonのシリアライゼーションとjedis種類はちょうどツール、既に十分のインスタンスです。
- Jedisを設定することはできません
- 次のようにユーザーが、改善されたコードをBeanUtilインスタンスを作成することができません
public BeanUtil {
// 禁用 BeanUtil 构建
private BeanUtil(){}
// 这里我们可以使用 bean 的全路径 => bean 实例来缓存 bean
static Map<String,Object> beansCache = new ConcurrentHashMap<String,Object>();
static{
// 初始化时,在内容缓存这些 bean 的实例,因为 jedis 依赖于 serializable ,需要需要先创建 serializable
Serializable serializable = createSerializable();
beansCache.put(Serializable.class.getSimpleName(),serializable);
Jedis jedis = createJedis();
beansCache.put(jedis.class.getSimpleName(),jedis);
}
static Serializable createSerializable(String type){
Serializable serializable = beansCache.get("serializable");
if(serializable != null)return serializable;
switch(type){
case "kryo": // kryo 不能用单例,请忽略本问题,示例而已
return new KryoSerializable();
case "protostuff":
return new protostuffSerializable();
default:
return new FastJsonSerizlizable();
}
}
static Jedis createJedis(String serializableType){
Jedis jedis = new Jedis();
Serializable serializable = beansCache.get("serializable");
jedis.setSerializable(serializable);
return jedis;
}
//然后对外提供获取 Bean 的方法
public static Object getBean(String beanName){
return beansCache.get(beanName);
}
public static T getBean(Class<T> type){
return beansCache.get(type.getSimpleName());
}
}
このクラスの書き込みが暁明ある場合でも、一定期間後に、このクラスが初期化されますcreateXxとXXの多数を操作し、依存度は非常に複雑であり、その後、暁明は、波を最適化するための時間だと思うので、暁明の思考一つの解決策は、構文XMLを定義します
豆タグは、Beanを定義するために使用される、豆各XMLは完全な依存関係グラフBeanを得る解析し、それが使用REF属性に複雑である場合、そのプロパティを定義するプロパティを使用して、固有のID情報を有しています
<beans>
<bean id="serializable" class="com.xx.FastJsonSerizlizable" />
<bean id="jedis" class="com.xx.Jedis">
<property name="host" value="localhost" />
<property name="serializable" ref="serializable"/>
</bean>
</beans>
そして、依存関係の問題があり、私は最初に、シリアライズを作成jedisを作成したが、XMLビーン定義され、シリアライズは、ファイルの前に書かれている、暁明は、すべての豆を入れ、最初に既存の文字列REFと、方法を考えましたこのような定義は、
Map<String,BeanDefinition> beanDefinitions = new HashMap();
そして、依存関係ツリーにそれを解析するので、あなたが最初の葉を構築することができ、そのオブジェクトは、レイヤによって構築層であるが、トリッキーな状況もあり、それは循環依存であります
root
|-jedis
|- serializable
環の形成にどのようなことが、最も簡単なAはB、Bに循環依存依存していることは途中または最後、Aに依存している多くの依存、ABCA
最も独創的解決策は、あなたが彼らのコンストラクタとがあり、その後、プロパティ値でターゲットセットを設定することはできません、我々は最初にそれらのすべてを作成するためにコンストラクタを使用することができるようになっています。したがって、注入の構成は、循環依存の方法によってプロパティを解消することができます。
そして、私たちのBeanUtilは、そのようになる代わりに、エンティティクラスの工場と呼ばれるユーティリティクラスを考えることはできません
public BeanFactory {
Map<String,BeanDefinition> beanDefinitions = new HashMap();
// 这里我们可以使用 bean 的全路径 => bean 实例来缓存 bean
Map<String,Object> beansCache = new ConcurrentHashMap<String,Object>();
{
// 加载 xml bean 配置文件
beanDefinitions = loadXml(contextConfigurations:String []);
//实例化所有 bean
beansCache = instanceBeans(beanDefinitions);
}
//然后对外提供获取 Bean 的方法
public Object getBean(String beanName){
return beansCache.get(beanName);
}
public T getBean(Class<T> type){
return beansCache.get(type.getSimpleName());
}
}
これは、完全に十分な持っているようだが、私は私のクラスの一つは、私がこのような接続、ファイル、リソースなどのいくつかのリソースを取得したい、とクラスの破壊でリソースを再利用したい時に初期化する必要があり、この時のプログラマのA質問しかし、上記によると、それを行うにはどのような方法がありませんでした。
リトルは、これは私があなたにいくつかのインターフェイスを提供し、簡単にハンドルにある、と述べ、あなたが見つけた場合、Beanのインスタンスは、あなたが私はあなたがそれを呼び出すことができ、対応するプロセス内のインタフェースを実装しなければならないとき、私は、暁明ようになるだろう何を実現します追加した2つのインターフェイス
public interface InitializingBean{
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean{
void destroy() throws Exception;
}
プログラマの問題が解決され、その後、プログラマBは言った、方法はあり、むしろ私の現在のクラスよりも、初期化プロセスビーンのすべてを傍受することができ、私はプロキシクラスにすべてのサービスをしたい、Iこの方法でトランザクションサービスを追加したいです。
リトルは、まあ、私は、Beanのプロパティを超える注入され入れ、暁明は、このようなインターフェイスから提供され、豆の初期化前に初期化されるので、あなたのBeanに、あなたは、私に戻って、その後Beanを飾ると、言いました後、あなたが注意を払っていない、Beanを変更するために来ることができ、これは、フィルタリング操作を行うには、グローバルではなく、あなたの個人的な豆のためであります
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException ;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
}
Cプログラマと、この時点で質問を、私はBeanAを作成したが、私はああBeanCを得ることができますどのように、私はCのプロパティのいくつかを見てみたいです。
本当に迷惑、私はちょうどマップを置くフィクションではありません、私は、このインターフェイスでのHelloたBeanFactoryを与えた、とそう、こんにちはました
public interface BeanFactoryAware{
void setBeanFactory(BeanFactory beanUtil);
}
これは、その後、DはI setBeanFactory、と私はグローバルプロセッサを作成したときに、尋ね実装、または大きな頭の後に実行しているだろう。
リトルの下で、私は実行順序を終えよ、私たちは、Beanのライフサイクルと呼ばれる、道を名前を取った後、私は、次のライフサイクルを終え、あなたについてどのように語られていないいくつかの実用的なインターフェース、Bean名を提供し、言いました
反射创建 Bean
填充对象属性
BeanNameAware.setBeanName();
BeanFactoryAware.setBeanFactory ();
BeanPostProcessor.postProcessBeforeInitialization(); 多个
InitializingBean.afterPropertiesSet()
BeanPostProcessor.postProcessAfterInitialization(); 多个
DisposableBean.destory()
Eは、プログラマ、xml構成面倒は、JDK1.5がコメントを持っていない、私はあなたが私は詠唱のインスタンスを作成し、私のクラス、助けをスキャンし、上のロゴを追加したいと言いました
それから私の必要性、私は財産上のロゴを追加し、あなたはまた、種類に応じて、依存クラスを検索して、対応するインスタンスを作成することができ、比較のこの種を作成するプロセスならば、助け私は、うまくそれらに価値を置きます複雑な、自分自身を作成するには、その後、私はメソッドを定義し、あなたに戻ってそれを置く、ロゴ豆を追加し、あなたはコンテナに読み込みます。
だから、暁明も追加@Component
のコンポーネントを表すために@Bean
カスタムインスタンスを表すために、作成され@Autowired
たオブジェクトを注入する@PostConstruct
初期化クラスを実行するために@PreDestroy
仕事をするために、クラスを破壊し、クラスのライフサイクルはそうなります
反射创建 Bean
填充对象属性
BeanNameAware.setBeanName();
BeanFactoryAware.setBeanFactory ();
BeanPostProcessor.postProcessBeforeInitialization(); 多个
PostConstruct
InitializingBean.afterPropertiesSet()
BeanPostProcessor.postProcessAfterInitialization(); 多个
PreDestroy
DisposableBean.destory()
しかし、その後の義務の一つの原則に基づいて、getBeanメソッドを提供する、たBeanFactoryインタフェースに抽象化前のXML形式、暁明との互換性のために、ビーンたBeanFactoryは仕事をするために解決すべきではありません。
次いで、ビーン定義をロードするためのインタフェースを作成する、2つの実装XmlBeanRegistry、AnnotationBeanRegistryがある豆は、ワンタイムの外部インターフェイスを提供する、他の登録された豆の方法を追加することも考慮に入れた後、合併後に定義されたロード
public interface BeanFactoryPostProcessor{
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
あなたは、コンテナの中に独自のカスタムBeanを追加することができます私のカスタム実装を送った後BeanDefinition私が尋ねるとしてインスタンス化あなたのBean定義書かれたルールを、置くことができます
リトル・プロモーション
書き込みは容易ではない、私はgiteeポイントスター、フォーク、プット・バグへの歓迎、オープンソースソフトウェアのサポートを期待して、私のガジェット。
エクセル共通インポートとエクスポート、サポートエクセル数式
のブログのアドレス:https://blog.csdn.net/sanri1993/article/details/100601578
gitee:https://gitee.com/sanri/sanri-excel-poi
ガジェットは、データベースからコードを生成、テンプレートコードを使用し、いくつかのプロジェクトは、多くの場合に使用することができます
ブログのアドレス:https://blog.csdn.net/sanri1993/article/details/98664034
gitee:https://gitee.com/ sanri / sanri-ツール-達人