Professional Documents
Culture Documents
2 Anotacije
2 Anotacije
Anotacije
Meta podaci koji se na nivou izvornog
koda dodeljuju:
paketima , klasama,
metodama, atributima, parametrima metoda,
konstruktorima i
lokalnim varijablama.
JavaDoc, XDoclet
2/29
Anotacije
Ovako dodeljeni meta podaci se mogu
kasnije prepoznati i koristiti u toku
izvrenja programa (run-time) ili tokom
prevoenja.
Sa stanovita sintakse, anotacija se
dodaje kao:
@MojaAnotacija
3/29
Anotacija je interfejs
Specijalan interfejs:
4/29
Dodela anotacije
@ClassInfo(
author = "Milan Vidakovic",
version = "1.0"
)
public class AnnotationDemo {
...
}
5/29
Anotacija sa jednim elementom
Primer:
public @interface AttributeInfo {
String value();
}
Anotacija tipa AttributeInfo ima samo jedan
element i njegov podrazumevan naziv je value.
@AttributeInfo("Izbaciti u sledecoj
verziji")
int att = 1;
6/29
Anotacije bez elemenata
Primer:
public @interface Test {}
...
@Test public void f() { ... }
7/29
Meta-anotacije
Anotacije o anotacijama
Sistemske meta-anotacije:
@Retention nivo ukljuenja anotacije u
program
@Target emu se pridruuje anotacija
@Documented da li e pridruena anotacija
biti dokumentovana JavaDoc alatom ili nekim
drugim
8/29
@Retention
Tri vrste:
@Retention(RetentionPolicy.SOURCE)
anotacije se ne ugrauju u class datoteke
@Retention(RetentionPolicy.CLASS)
anotacije se ugrauju u class datoteke, ali se ne
mogu proitati refleksijom
@Retention(RetentionPolicy.RUNTIME)
anotacije se ugrauju u class datoteke i mogu se
proitati refleksijom
9/29
@Target
Osam varijanti:
@Target(ElementType.ANNOTATION_TYPE)
za definiciju meta-anotacije
@Target(ElementType.CONSTRUCTOR)
anotacija se moe dodeliti samo konstruktorima
@Target(ElementType.FIELD)
anotacija se moe dodeliti samo atributima
@Target(ElementType.LOCAL_VARIABLE)
anotacija se moe dodeliti samo lokalnim promenljivama
10/29
@Target
Nastavak:
@Target(ElementType.METHOD)
anotacija se moe dodeliti samo metodama
@Target(ElementType.PACKAGE)
anotacija se moe dodeliti samo deklaraciji paketa
@Target(ElementType.PARAMETER)
anotacija se moe dodeliti samo parametrima metoda
@Target(ElementType.TYPE)
anotacija se moe dodeliti samo definiciji klase, interfejsa,
enumeracije ili anotacije
11/29
Anotacije i refleksija
Prilikom definicije anotacije, mora se
navesti @Retention meta-anotacija:
@Retention(RetentionPolicy.RUNTIME)
Poeljno je i precizirati za koji entitet se
vezuje anotacija - @Target anotacija
Koristi se metoda getAnnotation(Class
annotationInterface) klasa Class, Method i
Field.
12/29
AnnotationProcessing Tool
@SuppressWarnings({"unchecked",
"depricated"})
iskljuuje upozorenja zadatog tipa
14/29
java.lang.annotation anotacije
@Documented
da li da se ukljui u javadoc dokumentaciju
@Inherited
anotacija se trai u roditeljskoj klasi ako ne postoji u
klasi naslednici
@Retention
nivo ukljuenja anotacije
@Target
kome se dodeljuje anotacija
15/29
Upotreba
EJB
Web servisi
ostalo
16/29
EJB Session Bean
@Stateless
public class HelloBean implements HelloRemote
{
17/29
EJB Remote interfejs
Anotacijom @Remote definie se Remote
interfejs
import javax.ejb.Remote;
@Remote
public interface Hello {
public String hello();
}
18/29
EJB Local interfejs
Anotacijom @Local definie se Local interfejs
import javax.ejb.Local;
@Local
public interface DrugiLocal {
public long f();
}
19/29
EJB Entity
@Entity
public class Book implements Serializable {
private Integer id;
private String title;
public Book(Integer id, String title) {
this.id = id;
this.title = title;
}
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
20/29
}
Web Service bean
@Stateless
@WebService(
endpointInterface = "web_service.EchoSEI",
serviceName = "EchoServis",
targetNamespace="http://web_servis_ns")
@Remote(EchoSEI.class)
public class EchoBean {
public String echo(String in) throws RemoteException
{
return "WS response: " + in;
}
}
21/29
Web Service SEI
@WebService(
name = "EchoProxy",
targetNamespace="http://web_servis_ns")
@SOAPBinding(
style = Style.RPC,
parameterStyle=ParameterStyle.WRAPPED,
use=Use.LITERAL)
@Remote
public interface EchoSEI {
@WebMethod
String echo(String in) throws RemoteException;
}
22/29
Ostalo
Primer "nove" upotrebe Swing oslukivaa
Umesto prijavljivanja oslukivaa, napie
se anotacija iznad metode
Koristi se klasa Proxy i InvocationHandler
interfejs
23/29
Klasa Proxy
Kreira dinamiku proxy klasu i njene instance
Instancira se navoenjem class loader-a, liste
interfejsa koje implementira i reference na
objekat koji implementira InvocationHandler
intefejs
InvocationHandler interfejs ima metodu invoke
koja se poziva kada se pozove bilo koja metoda
proxy klase
24/29
Klasa Proxy
Motivacija: imamo interfejs koji se mora
run-time implementirati
Realizacija: kreira se objekat klase Proxy,
koji se moe kastovati u pogodan interfejs
(koji implementira)
25/29
Primer
class ButtonFrame extends JFrame {
public ButtonFrame() {
setTitle("ButtonTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
panel = new JPanel();
add(panel);
blueButton = new JButton("Blue");
redButton = new JButton("Red");
panel.add(blueButton);
panel.add(redButton);
ActionListenerInstaller.processAnnotations(this);
}
@ActionListenerFor(source="blueButton")
public void blueBackground() {
panel.setBackground(Color.BLUE);
}
@ActionListenerFor(source="redButton")
public void redBackground() {
panel.setBackground(Color.RED);
} 26/29
}
ActionListenerFor
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionListenerFor
{
String source();
}
27/29
ActionListenerInstaller
public static void processAnnotations(Object obj) {
try {
Class cl = obj.getClass();
for (Method m : cl.getDeclaredMethods()) {
ActionListenerFor a =
m.getAnnotation(ActionListenerFor.class);
if (a != null) {
Field f = cl.getDeclaredField(a.source());
f.setAccessible(true);
addListener(f.get(obj), obj, m);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
28/29
ActionListenerInstaller
public static void addListener(Object source, final Object frame,
final Method m) throws NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method mm, Object[] args)
throws Throwable {
return m.invoke(frame);
}
};