Eine Bean ist eine Java-Klasse mit Methodennamen, die den Java Bean-Richtlinien (auch als Entwurfsmuster bezeichnet) für Eigenschaften , Methoden und Ereignisse folgen. Daher ist jede öffentliche Methode der Bean-Klasse, die nicht Teil einer Eigenschaftsdefinition ist, eine Bean-Methode. Eine Java-Klasse, auch wenn entweder eine Eigenschaft als einziges Mitglied vorhanden ist (natürlich ist ein öffentlicher Getter und Setter erforderlich), eine öffentliche Methode als einziges Mitglied oder nur eine Registrierungsmethode für öffentliche Ereignis-Listener eine Java-Bean ist. Darüber hinaus kann die Eigenschaft entweder eine schreibgeschützte Eigenschaft sein (hat eine Getter-Methode, aber keinen Setter) oder eine schreibgeschützte Eigenschaft (hat nur eine Setter-Methode). Die Java-Bean muss eine öffentliche Klasse sein, damit sie für jedes Beanbox-Tool oder -Container sichtbar ist. Der Container muss ihn instanziieren können. Daher muss es auch einen öffentlichen Konstruktor haben. Die JavaBeans-SpezifikationFür eine Bean ist kein expliziter oder standardmäßiger öffentlicher Null-Argument-Konstruktor erforderlich, damit ein Container ihn instanziieren kann. Wenn Sie eine Datei (mit der Erweiterung .ser) bereitstellen könnten, die eine serialisierte Instanz enthält, könnte ein Beanbox-Tool diese Datei verwenden, um eine Prototyp-Bean zu instanziieren. Andernfalls muss die Bean über einen öffentlichen Konstruktor mit null Argumenten verfügen, entweder explizit oder standardmäßig.
Sobald die Bean instanziiert ist, kann die Java Bean-API (java.beans. *) Sie überprüfen und Methoden darauf aufrufen. Wenn keine Klasse verfügbar ist, die die Schnittstelle BeanInfo implementiert oder eine BeanInfo-Implementierung, die SimpleBeanInfo-Klasse, erweitert, umfasst die Introspektion die Verwendung von Reflektion (implizite Introspektion), um die von einer Ziel-Bean unterstützten Methoden zu untersuchen und dann einfache Entwurfsmuster (die Richtlinien) anzuwenden, aus denen abgeleitet werden kann diese Methoden, welche Eigenschaften, Ereignisse und öffentlichen Methoden unterstützt werden. Wenn eine Klasse verfügbar ist, die die Schnittstelle BeanInfo implementiert (für eine Bean Foo muss sie FooBeanInfo heißen), umgeht die API die implizite Introspektion und verwendet öffentliche Methoden (getPropertyDescriptor (), getMethodDescriptors (), getEventSetDescriptors ()) dieser Klasse, um die zu erhalten Information. Wenn eine Klasse zur Erweiterung von SimpleBeanInfo verfügbar ist, Abhängig davon, welche der öffentlichen SimpleBeanInfo-Methoden (getPropertyDescriptor (), getMethodDescriptors (), getEventSetDescriptors ()) überschrieben werden, werden diese überschriebenen Methoden verwendet, um Informationen abzurufen. Für eine Methode, die nicht überschrieben wird, wird standardmäßig die entsprechende implizite Selbstbeobachtung verwendet. Eine Bohne muss ohnehin instanziiert werden, auch wenn keine implizite Selbstbeobachtung durchgeführt wird. Somit ist die Anforderung eines öffentlichen Zeri-Args-Konstruktors. Natürlich ist die Schnittstelle Serializable oder Externalizable nicht erforderlich, damit sie erkannt wird. In der Java Bean-Spezifikation heißt es jedoch: "Wir möchten auch, dass es für den häufigen Fall einer winzigen Bean, die einfach ihren internen Status speichern und nicht darüber nachdenken möchte," trivial "ist." Daher müssen alle Beans eine serialisierbare oder externisierbare Schnittstelle implementieren. Insgesamt, Die JavaBeans-Spezifikation ist nicht genau, was eine Bean ausmacht. "Das Schreiben von JavaBeans-Komponenten ist überraschend einfach. Sie benötigen kein spezielles Tool und müssen keine Schnittstellen implementieren. Beim Schreiben von Beans müssen Sie lediglich bestimmte Codierungskonventionen befolgen. Sie müssen lediglich Ihre Klasse so aussehen lassen, wie sie aussieht eine Bohne - Werkzeuge, die Beans verwenden, können Ihre Bohne erkennen und verwenden. " Trivialerweise ist sogar die folgende Klasse eine Java Bean,
public class Trivial implements java.io.Serializable {}
Angenommen, ein Bean-Konstruktor hat einige Parameter. Angenommen, einige sind einfache Typen. Der Container weiß möglicherweise nicht, welche Werte ihm zugewiesen werden sollen. Selbst wenn dies der Fall ist, kann die resultierende Instanz möglicherweise nicht wiederverwendet werden. Dies ist möglicherweise nur dann sinnvoll, wenn der Benutzer wie in Spring Beans beispielsweise Anmerkungen oder XML-Konfigurationsdateien konfigurieren (Werte angeben) kann. Angenommen, einige Parameter sind Klassen- oder Schnittstellentypen. Auch hier weiß der Container möglicherweise nicht, welche Werte ihm zugewiesen werden sollen. Dies ist möglicherweise nur dann sinnvoll, wenn der Benutzer bestimmte Objekte beispielsweise durch Anmerkungen oder XML-Konfigurationsdateien konfigurieren (angeben) kann. Selbst in Spring (über XML-Konfigurationsdateien) ist das Zuweisen bestimmter Objekte (mit Zeichenfolgennamen) zu Konstruktorargumenten (Attribut oder Element von Konstruktorargumenten) nicht typsicher, sondern im Grunde wie eine Ressourceninjektion. Das Verweisen auf andere Spring Beans (Collaborators genannt; via Element in einem Konstruktorargumentelement) ist im Grunde genommen eine Abhängigkeitsinjektion und somit typsicher. Offensichtlich kann eine Abhängigkeit (Collaborator Bean) einen Konstruktor mit injizierten Parametern haben. Diese injizierten Abhängigkeiten haben möglicherweise einen Konstruktor mit Parametern und so weiter. In diesem Szenario benötigen Sie letztendlich einige Bean-Klassen (z. B. MyBean.class), die der Container durch einfaches Aufrufen von new MyBean () instanziieren kann, bevor er die anderen zusammenarbeitenden Beans über die Abhängigkeitsinjektion von Konstruktoren erstellen kann - daher die Anforderung für Die Beans müssen einen öffentlichen Zero-Args-Konstruktor haben. Angenommen, ein Container unterstützt keine Abhängigkeitsinjektion und / oder erlaubt es nicht, dem Konstruktor über einige Anmerkungen oder XML-Konfigurationsdateien wie in Spring einfache Werte zuzuweisen. Bean-Konstruktoren sollten keine Parameter haben. Sogar eine Spring-Beans-Anwendung würde einige Beans benötigen, um einen öffentlichen Konstruktor mit null Argumenten zu haben (z. B. in einem Szenario, in dem Ihre Spring-Anwendung keine Bean mit nur einfachen Typen als Konstruktorargumente hat).
JSF-verwaltete Beans werden in einem Webcontainer ausgeführt. Sie können entweder mit der Annotation @ManagedBean oder mit einer Anwendungskonfigurationsressourcendatei manage-bean.xml konfiguriert werden. Es unterstützt jedoch die Injektion nur über die Ressourceninjektion (nicht typsicher). Nicht für die Injektion auf Konstruktoren geeignet. Die JSF-Spezifikationerfordert, dass verwaltete Beans einen öffentlichen Konstruktor mit null Argumenten haben müssen. Darüber hinaus heißt es: „Ab Version 2.3 dieser Spezifikation wird von der Verwendung der in diesem Abschnitt angegebenen verwalteten Bean-Funktion dringend abgeraten. Eine bessere und kohärentere integrierte Lösung zur Lösung des gleichen Problems ist die Verwendung von Contexts and Dependency Injection (CDI), wie in JSR-365 angegeben Die CDI-Spezifikation übernimmt die Managed Beans-Spezifikation, die für alle Container der JEE-Plattform gilt, nicht nur für die Webschicht. Daher muss der Webcontainer die CDI-Spezifikation implementieren.
Hier ist ein Auszug aus der Managed Bean-Spezifikation
„Managed Beans sind Container-verwaltete Objekte mit minimalen Anforderungen, die auch unter dem Akronym„ POJOs “(Plain Old Java Objects) bekannt sind. Sie können als eine auf der Java EE-Plattform erweiterte Version des JavaBeans-Komponentenmodells auf der Java SE-Plattform angesehen werden …. Der Leser wird nicht übersehen, dass Managed Beans einen Vorläufer in der gleichnamigen Funktion der JavaServer Faces (JSF) -Technologie haben. Managed Beans, wie in dieser Spezifikation definiert, stellen eine Verallgemeinerung der in JSF gefundenen dar. Insbesondere können verwaltete Beans überall in einer Java EE-Anwendung verwendet werden, nicht nur in Webmodulen. Im Basiskomponentenmodell müssen verwaltete Beans beispielsweise einen Konstruktor ohne Argumente bereitstellen, aber eine Spezifikation, die auf verwalteten Beans aufbaut, z. B. CDI (JSR-299). kann diese Anforderung lockern und es Managed Beans ermöglichen, Konstruktoren komplexere Signaturen bereitzustellen, sofern sie einigen genau definierten Regeln folgen ... Eine Managed Bean darf nicht sein: eine letzte Klasse, eine abstrakte Klasse, eine nicht statische innere Klasse . Eine verwaltete Bean ist im Gegensatz zu einer normalen JavaBean-Komponente möglicherweise nicht serialisierbar. “ Daher ermöglicht die Spezifikation für verwaltete Bohnen, die auch als POJOs oder POJO-Beans bezeichnet wird, eine Erweiterung wie in CDI.
In der CDI-Spezifikation werden verwaltete Beans wie folgt neu definiert: Bei Ausführung in Java EE ist eine Java-Klasse der obersten Ebene eine verwaltete Bean, wenn sie die Anforderungen erfüllt:
• Es ist keine innere Klasse. • Es ist eine nicht abstrakte Klasse oder mit @Decorator versehen. • javax.enterprise.inject.spi.Extension wird nicht implementiert. • Es ist nicht mit @Vetoed oder in einem mit @Vetoed kommentierten Paket versehen. • Es hat entweder einen geeigneten Konstruktor: Die Klasse hat einen Konstruktor ohne Parameter, oder die Klasse deklariert einen Konstruktor mit der Bezeichnung @Inject.
Alle Java-Klassen, die diese Bedingungen erfüllen, sind verwaltete Beans. Daher ist keine spezielle Deklaration erforderlich, um eine verwaltete Bean zu definieren. Oder
wenn es von einer anderen Java EE-Spezifikation als verwaltete Bean definiert wird und wenn
• Es ist nicht mit einer EJB-Komponenten-definierenden Annotation versehen oder in ejb-jar.xml als EJB-Bean-Klasse deklariert.
Im Gegensatz zu Spring Beans werden Konstruktoren mit einfachen Typen nicht unterstützt. Dies ist möglicherweise möglich, wenn die Konfiguration mit XML-Konfigurationsdateien wie in Spring oder Anmerkungen unterstützt wird.
EJBs werden in einem EJB-Container ausgeführt. Seine Spezifikationsagt: "Eine Session-Bean-Komponente ist eine verwaltete Bean." "Die Klasse muss einen öffentlichen Konstruktor haben, der keine Argumente akzeptiert", heißt es sowohl für Session-Bean als auch für nachrichtengesteuerte Bean. Außerdem heißt es: "Die Session-Bean-Klasse ist nicht erforderlich, um die SessionBean-Schnittstelle oder die serialisierbare Schnittstelle zu implementieren. “ Aus dem gleichen Grund wie JSF-Beans, bei denen es sich bei der EJB3-Abhängigkeitsinjektion im Grunde genommen um eine Ressourceninjektion handelt, unterstützen JSF-Beans keine Konstruktoren mit Argumenten, dh über die Abhängigkeitsinjektion. Wenn der EJB-Container jedoch CDI implementiert, lautet „Optional: Die Klasse verfügt möglicherweise über eine Zusätzlicher Konstruktor, der mit der Annotation "Inject" versehen ist ", heißt es sowohl für Session-Bean als auch für Message-Driven-Bean, weil" ein EJB, der in ein CDI-Bean-Archiv gepackt und nicht mit javax.enterprise.inject.Vetoed-Annotation versehen ist, als CDI-fähig angesehen wird Bohne."