Guice jest biblioteką od Google, której ideę stanowi możliwość zastąpienia różnego rodzaju fabryk obiektów, tworzenia obiektów za pomocą operatora new. Zapewnia ona ponadto mechanizmy zbliżone do dependency injection.
(więcej…)
Archiwum dla kategorii ‘Java’
Wstęp do Google Guice
czwartek, Sierpień 26, 2010Autor: Adam Andrzejewski
PRAKTYCZNY ENVERS
piątek, Sierpień 20, 2010Envers jest dodatkiem do Hibernate’a pozwalającym na automatyczne zapisywanie historii zmian encji (audytu). Envers używa pojęcia rewizji – co oznacza, że każda zmiana dowolnej (audytowalnej) encji tworzy nową rewizję. Nowy rekord jest zapisany do tabeli, a na podstawie starego zostaje utworzona rewizja i zapisana do dodatkowej tabeli wraz z poprzednimi wartościami.
Autor: Mateusz Mrozewski
W walce o jakość kodu
czwartek, Czerwiec 17, 2010Wielu programistów, zwłaszcza początkujących, nie zwraca uwagi na jakość kodu, który tworzą. Czasami brak nam czasu lub wiedzy na wytworzenie kodu, który – poza tym że działa – jest czytelny, zrozumiały i wydajny. Jakość kodu to nie tylko sławne „do not repeat yourself” (swoją drogą często zapomniane…), ale także całe zestawy reguł dbające o prostotę utrzymania, łatwość zrozumienia, wydajność itd. Na szczęście nie musimy znać ich wszystkich, bo istnieją narzędzia które mogą nas wspierać w pisaniu kodu wysokiej jakości. Jedno z nich chciałbym przedstawić w tym artykule – jest to Sonar.
Autor: Adam Andrzejewski
JSR-303 – przepis na fasolkę. Bardzo dobrą poniekąd. Cz. 1
czwartek, Luty 11, 2010Finalna wersja specyfikacji JSR-303: Bean Validation ukazała się światu pod koniec ubiegłego roku (2009). Jest to kolejny przysmak a’la carte z renomowanej kuchni Gavin’a King’a i spółki, który doczekał się formalnej specyfikacji. Zatem – delektujmy się przez chwilę…
Dla osób niewtajemniczonych wyjaśniam, że mam na myśli produkt hibernate-validator, który jest protoplastą specyfikacji.
Wraz z nią otrzymaliśmy jej implementację referencyjną w postaci produktu hibernate-validator w wersji 4.
Świadomy tego, że bezapelacyjnie każdego ta historia urzekła przejdę do konkretów.
Dlaczego w ogóle o tym piszę? istnieje co najmniej kilka powodów:
- Jest to nowy standard w ramach Javy.
- Będzie wchodził w skład JEE 6.
- Bardzo łatwo się go używa – również na platformie SAP NetWeaver.
- Posiada nowe rozbudowane API oraz nowe możliwości rozszerzeń (np. tzw. “composite constraints”).
- W sposób przezroczysty integruje się z już posiadanym kodem.
Ponieważ jest to artykuł subiektywny, nie zamierzam w nim wymieniać wszystkich właściwości oraz różnic w specyfikacji JSR 303 w stosunku do starego hibernate-validator’a. Ze szczegółami można zawsze zapoznać się pobierając specyfikację ze stron Java Community Process.
Moim zdaniem bardzo istotna jest rozbudowa specyfikacji o możliwość definiowania mechanizmów walidacji za pomocą deskryptorów XML. Być może niektórzy czytelnicy posądzą mnie tutaj o herezję, ponieważ dziesiątki deskryptorów dostępnych w JEE to swoiste “małe piekiełko”. W przypadku walidatora jest to bardzo dobry pomysł o czym świadczą silne argumenty:
- Deskryptory pozwalają na zastosowanie walidacji w beanach dostarczanych w postaci bibliotek,
- Definicje w deskryptorach uniezależniają walidowane komponenty od API walidatora oraz własnych walidatorów w formie rozszerzeń.
Poniżej przedstawiam przykład kodu z zastosowaniem adnotacji oraz odpowiednika z zastosowaniem deskryptora xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | // Person.java package test.beans; import javax.validation.constraints.NotNull; import javax.validation.Size; import javax.validation.constraints.Past; import java.util.List; import java.util.Date; import javax.validation.Valid; public class Person { // wymuszenie wartości różnej niż null @NotNull(message="Imię nie może być puste") private String name; // wymuszenie wartości różnej niż null @NotNull(message="Nazwisko nie może być puste") private String surname; // wymuszamy datę przeszłą w stosunku do czasu systemowego @Past(message="Należy podać datę przeszłą") private Date birthDate; // oczekiwanie, że w kolekcji będzie co najmniej jeden element @Size(min=1,message="Należy podać co najmniej jeden adres") @Valid // wskazanie aby implementacja wykonała również walidację adresów private List<Address> adrList; (...) } ---------------------------------------------------------- // Address.java package test.beans; import javax.validation.constraints.NotNull; public class Address { // wymuszenie wartości różnej niż null @NotNull(message="Miasto nie może być puste") private String city; (...) } |
Stan analogiczny do powyższego kodu możemy uzyskać za pomocą następujących definicji w deskryptorze xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?xml version="1.0" encoding="UTF-8"?> <!-- sample-constraints.xml --> <constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"> <default-package>test.beans</default-package> <bean class="Person" ignore-annotations="true"> <field name="name"> <constraint annotation="javax.validation.constraints.NotNull"> <message>Imię nie może być puste</message> </constraint> </field> <field name="surname"> <constraint annotation="javax.validation.constraints.NotNull"> <message>Nazwisko nie może być puste</message> </constraint> </field> <field name="birthDate"> <constraint annotation="javax.validation.constraints.Past"> <message>Należy podać datę przeszłą</message> </constraint> </field> <field name="adrList"> <constraint annotation="javax.validation.constraints.Size"> <message>Należy podać co najmniej jeden adres</message> <element name="min">1</element> </constraint> <valid/> </field> </bean> <bean class="Address" ignore-annotations="true"> <field name="city"> <constraint annotation="javax.validation.constraints.NotNull"> <message>Miasto nie może być puste</message> </constraint> </field> </bean> </constraint-mappings> |
Nie jest trudno wywnioskować, że wszystkie ograniczenia zdefiniowane w kodzie źródłowym mają swoje odpowiedniki w deskryptorze. Aby powyższe przykłady uruchomić, konieczne jest jeszcze skonfigurowanie całego “silnika” walidacji.
Konfigurację realizuje się przez zamieszczenie w katalogu META-INF pliku o nazwie validation.xml, który jest deskryptorem konfiguracji JSR-303.
Oto przykład pliku:
1 2 3 4 5 6 7 8 9 | <?xml version="1.0" encoding="UTF-8"?> <validation-config xmlns="http://jboss.org/xml/ns/javax/validation/configuration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd"> <default-provider>org.hibernate.validator.HibernateValidator</default-provider> <constraint-mapping>META-INF/sample-constraints.xml</constraint-mapping> </validation-config> |
W powyższym pliku określono następujące właściwości silnika:
- Default-provider wskazuje dostawcę implementacji JSR-303, którym jest oczywiście hibernate validator
- Constraint-mapping wskazuje na dodatkowy deskryptor xml z definicją ograniczeń, można zdefiniować wiele plików z definicją ograniczeń
Na deser pozostał mi jeszcze prościutki przykład uruchomienia walidacji w kodzie z zastosowaniem poprzednich przykładów.
Oto on:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // ValidationTest.java package test.beans; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.ValidatorFactory; public class ValidationTest { public static void main(String[] argv) { ValidationTest vt = new ValidationTest(); Person p = new Person(); p.name= "John"; t.validateBean(p); return; } public void validateBean(Person p) { ValidatorFactory vf = Validation.buildDefaultValidatorFactory(); Set<ConstraintViolation> violationSet = vf.getValidator().validate(p); for(ConstraintViolation cv : violationSet ) { System.out.println(cv.getMessage()); } return; } } |
Smacznej walidacji
Autor: Daniel Ramotowski
Hibernate i efektywne sekwencje
wtorek, Grudzień 15, 2009Do napisania kilku słów na temat optymalizacji używania generatorów w Hibernate 3 natchnął mnie kolega z pracy Krzysiek – prawdziwy specjalista Oracle i tropiciel motocyklistów w białych pantoflach
(użyłem określenia “tropiciel”, w celu podkreślenia swobodnego charakteru tej publikacji i zwiększenia percepcji treści merytorycznych wśród czytelników; ma to oczywiście związek z pewnym zabawnym wydarzeniem ale nie o tym będzie tutaj mowa).
Autor: Daniel Ramotowski
Java – elementarz serializacji
poniedziałek, Sierpień 17, 2009Temat serializacji obiektów w języku Java jest z pozoru trywialny : wystarczy zaimplementować malutki interfejsik – i gotowe! Czasem jednak to, co wydaje się tak oczywiste, przysparza inżynierom pracy na wiele dni…
Za większością publikacji, więc również i za tą, kryje się głębsza historia opowiadająca o pewnym systemie informatycznym zaimplementowanym w języku Java, który można opisać nośnymi przymiotnikami, takimi jak “skalowalny”, “rozproszony”, “wielowarstwowy” itd.
Jak powszechnie wiadomo (a jeżeli nie, to od tej chwili będzie), inżynierowie, którzy rozpraszają systemy
, bardzo często stosują mechanizmy związane z replikacją danych. Takim mechanizmem jest z całą pewnością rozproszony bufor (cache) obiektów Java i to na nim będziemy się teraz skupiać.
Stosując mechanizmy buforowania zawsze dbamy o to, aby obiekty były “serializowalne”, ponieważ zawartość bufora może być zapisywana również na dyski lub do baz danych. W przypadku bufora rozproszonego (tzn. takiego, który dba o to aby każdy z systemów miał taką samą zawartość bufora) obiekty są przesyłane przez sieć, co również wymusza serializację.
Tyle tytułem wstępu – teraz konkrety.
Autor: Daniel Ramotowski
